#Область ОписаниеПеременных

&НаКлиенте
Перем МенеджерПрототипов;

&НаКлиенте
Перем МенеджерФайлов;

&НаКлиенте
Перем МенеджерНаборовЗначений;

&НаКлиенте
Перем ПеремещениеВыполнено;

&НаКлиенте
Перем Типы;

&НаКлиенте
Перем Виды;

&НаКлиенте
Перем ТипыЗначения;

&НаКлиенте
Перем ВариантыЗаполнения;

&НаКлиенте
Перем Счетчики;

#КонецОбласти

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	ЗагрузитьРеквизитыИзМакетов();
	ЗагрузитьЭлементыУправленияИзМакетов();

	Элементы.ГруппаКоманды.Видимость = Ложь;

	УИ_ОбщегоНазначения.ФормаИнструментаПриСозданииНаСервере(ЭтотОбъект, Отказ, СтандартнаяОбработка, КоманднаяПанель);

КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)

	ИнициализироватьМенеджераПрототипов();
	ИнициализироватьМенеджераФайлов();

	ИнициализироватьМенеджераНаборовЗначений();
	ЗаполнитьНаборыЗначений();

	НастроитьОтображениеКоманд();

	ОбработатьИзменениеНастроекПроекта();
	Если ЗагружатьСвойстваИзФайла Тогда
		ВыполнитьЗагрузкуСвойствИзФайла();
	Иначе
		ВыполнитьЗагрузкуСвойствИзМакета();
	КонецЕсли;

	Если ЗначениеЗаполнено(ИмяФайлаДанныхИнструмента) Тогда
		УИ_ОбщегоНазначенияКлиент.ПрочитатьДанныеКонсолиИзФайла("КонсольКода",
																СтруктураОписанияСохраняемогоФайла(),
																Новый ОписаниеОповещения("ОткрытьФайлЗавершение",
			ЭтотОбъект),
																Истина);
	КонецЕсли;
	

КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементов_ФормыИЭлементыУправления

&НаКлиенте
Процедура ФормыИЭлементыУправленияПриАктивизацииСтроки(Элемент)

	ОпределитьСвойства();
	ОпределитьГруппуКоманд();
	СкрытьВсеСтраницыКромеТекущей();

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные <> Неопределено Тогда
		ПодключитьОбработчикОжидания("АктивизироватьТекущийЭлемент", 0.1, Истина);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ФормыИЭлементыУправленияПередУдалением(Элемент, Отказ)

	Отказ = Истина;
	ВыполнитьУдалениеФормыИлиЭлементаУправления();

КонецПроцедуры

&НаКлиенте
Процедура ФормыИЭлементыУправленияОкончаниеПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;

	Для Каждого СтрокаИсточник Из ПараметрыПеретаскивания.Значение Цикл
		Родитель = СтрокаИсточник.ПолучитьРодителя();
		Если Родитель = Неопределено Тогда
			СтрокиУровня = ФормыИЭлементыУправления.ПолучитьЭлементы();

		Иначе
			СтрокиУровня = Родитель.ПолучитьЭлементы();

		КонецЕсли;

		СтрокиУровня.Удалить(СтрокаИсточник);

	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ФормыИЭлементыУправленияПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
	СтандартнаяОбработка = Ложь;

	Если ПеремещениеВозможно() Тогда
		Перемещенные = Новый Массив;
		ВыполнитьПеремещение(ПараметрыПеретаскивания.Значение, Строка, Перемещенные, Истина);

	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементов_СвойстваФормИЭлементовУправления

&НаКлиенте
Процедура СвойстваФормИЭлементовУправленияВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)

	ЗначениеНачалоВыбора(Элемент, Неопределено, СтандартнаяОбработка);

КонецПроцедуры

//@skip-warning
&НаКлиенте
Процедура СвойстваФормИЭлементовУправленияДанныеВыбора_НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;
	РедактированиеДанныхВыбора("ДанныеВыбора");

КонецПроцедуры

//@skip-warning
&НаКлиенте
Процедура СвойстваФормИЭлементовУправленияДанныеВыбора_ГруппаКолонокНачалоВыбора(Элемент, ДанныеВыбора,
	СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;
	РедактированиеДанныхВыбора("ДанныеВыбора_ГруппаКолонок");

КонецПроцедуры

//@skip-warning
&НаКлиенте
Процедура СвойстваФормИЭлементовУправленияДанныеВыбора_КнопкаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;
	РедактированиеДанныхВыбора("ДанныеВыбора_Кнопка");

КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура СоздатьПрототип(Команда)

	НоваяСтрока = ФормыИЭлементыУправления.ПолучитьЭлементы().Добавить();
	НоваяСтрока.Модифицированность = Истина;
	НоваяСтрока.ИндексКартинки = ИндексКартинкиФормы(НоваяСтрока.Модифицированность);

	НовоеИмя = "Новая форма";
	НоваяСтрока.Имя = НовоеИмя;
	НоваяСтрока.Заголовок = НовоеИмя;
	НоваяСтрока.Тип = Типы.ФормаКлиентскогоПриложения;
	НоваяСтрока.Идентификатор = Новый УникальныйИдентификатор;
	НоваяСтрока.КнопкаПоУмолчанию = "";

	ПодготовитьСчетчики(НоваяСтрока.Идентификатор);
	ЗаполнитьСвойстваПервымЗначениемДанныхВыбора(НоваяСтрока);

	МенеджерПрототипов.ОткрытьПрототип(НоваяСтрока, ЭтаФорма, Ложь);

	Элементы.ФормыИЭлементыУправления.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();

КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьПрототипИзФайла(Команда)

	Оповещение = Новый ОписаниеОповещения("ПослеВыбораРасположенияФайлаДляЗагрузки", ЭтотОбъект);

	ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	ДиалогВыбораФайла.Фильтр = "*.json|*.json";
	ДиалогВыбораФайла.Расширение = "json";
	ДиалогВыбораФайла.МножественныйВыбор = Ложь;
	ДиалогВыбораФайла.Показать(Оповещение);

КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораРасположенияФайлаДляЗагрузки(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт

	Если ВыбранныеФайлы = Неопределено Тогда
		Возврат;
	КонецЕсли;

	РасположениеФайла = ВыбранныеФайлы[0];

	ДополнительныеПараметры = Новый Структура;
	ДополнительныеПараметры.Вставить("РасположениеФайла", РасположениеФайла);

	ОписаниеОповещенияОЗавершении = Новый ОписаниеОповещения("ЗагрузитьПрототипЗавершение", ЭтотОбъект,
		ДополнительныеПараметры);
	МенеджерФайлов.ЗагрузитьФайл(РасположениеФайла, Ложь, ОписаниеОповещенияОЗавершении);

КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьПрототипЗавершение(Адрес, ДополнительныеПараметры) Экспорт

	Идентификатор = "";
	Замена = Ложь;
	Если Не ПустаяСтрока(Адрес) Тогда
		Если ЗагрузитьПрототипНаСервере(Адрес, Идентификатор, Замена, ДополнительныеПараметры.РасположениеФайла) Тогда
			Строки = ФормыИЭлементыУправления.ПолучитьЭлементы();
			Для Каждого Строка Из Строки Цикл
				Если Строка.Идентификатор = Идентификатор Тогда
					ИдентификаторСтроки = Строка.ПолучитьИдентификатор();

					Если Замена Тогда
						МенеджерПрототипов.УдалитьФорму(Строка.Идентификатор);
					КонецЕсли;

					ВременныйМассив = Новый Массив;
					ВременныйМассив.Добавить(Строка);
					ЗагрузитьПрототипРекурсивно(ВременныйМассив);

					Прервать;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;

		Элементы.ФормыИЭлементыУправления.ТекущаяСтрока = ИдентификаторСтроки;
		Элементы.ФормыИЭлементыУправления.Развернуть(ИдентификаторСтроки, Истина);
	КонецЕсли;

КонецПроцедуры

&НаСервере
Функция ЗагрузитьПрототипНаСервере(Адрес, Идентификатор, Замена, РасположениеФайла)

	Результат = Ложь;

	ФормыИЭлементыУправленияНаСервере = РеквизитФормыВЗначение("ФормыИЭлементыУправления");

	ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
	ДвоичныеДанные.Записать(ИмяВременногоФайла);

	ФайлПрототипа = ДесериализоватьИзJSON(ИмяВременногоФайла, Истина);
	Если ФайлПрототипа.Количество() Тогда
		Идентификатор = ФайлПрототипа.Элементы[0].Идентификатор;
		ФормыИЭлементыУправленияИзМассиваРекурсивно(ФайлПрототипа.Элементы,
													ФормыИЭлементыУправленияНаСервере.Строки,
													Истина,
													Замена,
													РасположениеФайла);
		ЗначениеВРеквизитФормы(ФормыИЭлементыУправленияНаСервере, "ФормыИЭлементыУправления");

		Результат = Истина;
	КонецЕсли;

	Файл = Новый Файл(ИмяВременногоФайла);
	Если Файл.Существует() Тогда
		УдалитьФайлы(ИмяВременногоФайла);
	КонецЕсли;

	Возврат Результат;

КонецФункции

&НаКлиенте
Процедура СохранитьПрототип(Команда)

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	СтрокаПрототипа = ПолучитьСтрокуПрототипаРекурсивно(ТекущиеДанные);
	Если ЗначениеЗаполнено(СтрокаПрототипа.РасположениеФайла) Тогда
		СохранитьПрототипПоУказанномуРасположению(ТекущиеДанные, СтрокаПрототипа);
	Иначе
		Оповещение = Новый ОписаниеОповещения("ПослеВыбораРасположенияФайлаДляСохранения", ЭтотОбъект);

		ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
		ДиалогВыбораФайла.Фильтр = "*.json|*.json";
		ДиалогВыбораФайла.Расширение = "json";
		ДиалогВыбораФайла.МножественныйВыбор = Ложь;
		ДиалогВыбораФайла.ПолноеИмяФайла = СтрокаПрототипа.Заголовок;
		ДиалогВыбораФайла.Показать(Оповещение);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораРасположенияФайлаДляСохранения(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт

	Если ВыбранныеФайлы = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	СтрокаПрототипа = ПолучитьСтрокуПрототипаРекурсивно(ТекущиеДанные);
	СтрокаПрототипа.РасположениеФайла = ВыбранныеФайлы[0];

	СохранитьПрототипПоУказанномуРасположению(ТекущиеДанные, СтрокаПрототипа);

КонецПроцедуры

&НаКлиенте
Процедура СохранитьПрототипПоУказанномуРасположению(ТекущиеДанные, СтрокаПрототипа)

//	Адрес = "";
//	Если СохранитьПрототипНаСервере(СтрокаПрототипа.Идентификатор, Адрес) Тогда
//		Оповещение = Новый ОписаниеОповещения("ПослеСохраненияПрототипа", ЭтотОбъект);
//		МенеджерФайлов.СохранитьФайл(СтрокаПрототипа.РасположениеФайла, Адрес, Ложь, Оповещение);
//	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПослеСохраненияПрототипа(Результат, ДополнительныеПараметры) Экспорт

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;

	СтрокаПрототипа = ПолучитьСтрокуПрототипаРекурсивно(ТекущиеДанные);
	СтрокаПрототипа.Модифицированность = Ложь;
	СтрокаПрототипа.ИндексКартинки = ИндексКартинкиФормы(ТекущиеДанные.Модифицированность);

КонецПроцедуры

&НаКлиенте
Процедура ОткрытьПрототип(Команда)

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	СтрокаПрототипа = ПолучитьСтрокуПрототипаРекурсивно(ТекущиеДанные);

	СвойстваФормы = Новый Структура("Имя,Заголовок,Идентификатор");
	ЗаполнитьЗначенияСвойств(СвойстваФормы, СтрокаПрототипа);

	МенеджерПрототипов.ОткрытьПрототип(СвойстваФормы, ЭтаФорма);

КонецПроцедуры

&НаКлиенте
Процедура ПереместитьВверх(Команда)
	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	СтрокиУровня = ТекущиеДанные.ПолучитьРодителя().ПолучитьЭлементы();
	ИндексТекущейСтроки = СтрокиУровня.Индекс(ТекущиеДанные);
	ИндексПредыдущейСтроки = ИндексТекущейСтроки - 1;
	ВсегоСтрокУровня = СтрокиУровня.Количество() - 1;

	ДанныеПеремещения = Новый Структура;
	ДанныеПеремещения.Вставить("Идентификатор", ТекущиеДанные.Прототип);
	ДанныеПеремещения.Вставить("ИмяРодительскогоЭлемента", ТекущиеДанные.ИмяРодителя);

	Если ИндексТекущейСтроки > 0 Тогда
		ДанныеПеремещения.Вставить("ИмяПеремещаемогоЭлемента", ТекущиеДанные.Имя);

		ПредыдущиеДанные = СтрокиУровня[ИндексПредыдущейСтроки];
		ДанныеПеремещения.Вставить("ИмяЭлементаМесторасположения", ПредыдущиеДанные.Имя);

		МенеджерПрототипов.ПереместитьЭлементУправления(ДанныеПеремещения);

		СтрокиУровня.Сдвинуть(ИндексТекущейСтроки, -1);

	Иначе
		ДанныеПеремещения.Вставить("ИмяПеремещаемогоЭлемента", ТекущиеДанные.Имя);
		ДанныеПеремещения.Вставить("ИмяЭлементаМесторасположения", "");

		МенеджерПрототипов.ПереместитьЭлементУправления(ДанныеПеремещения);

		СтрокиУровня.Сдвинуть(ИндексТекущейСтроки, ВсегоСтрокУровня);

	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПереместитьВниз(Команда)
	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	СтрокиУровня = ТекущиеДанные.ПолучитьРодителя().ПолучитьЭлементы();
	ИндексТекущейСтроки = СтрокиУровня.Индекс(ТекущиеДанные);
	ИндексСледующейСтроки = ИндексТекущейСтроки + 1;
	ВсегоСтрокУровня = СтрокиУровня.Количество() - 1;

	ДанныеПеремещения = Новый Структура;
	ДанныеПеремещения.Вставить("Идентификатор", ТекущиеДанные.Прототип);
	ДанныеПеремещения.Вставить("ИмяРодительскогоЭлемента", ТекущиеДанные.ИмяРодителя);

	Если ИндексТекущейСтроки < ВсегоСтрокУровня Тогда
		// Здесь хитрость, перемещаем не выбранный элемент, а тот который после него)
		ДанныеПеремещения.Вставить("ИмяЭлементаМесторасположения", ТекущиеДанные.Имя);

		СледующиеДанные = СтрокиУровня[ИндексСледующейСтроки];
		ДанныеПеремещения.Вставить("ИмяПеремещаемогоЭлемента", СледующиеДанные.Имя);

		МенеджерПрототипов.ПереместитьЭлементУправления(ДанныеПеремещения);

		СтрокиУровня.Сдвинуть(ИндексТекущейСтроки, 1);

	Иначе
		ПервыеДанные = СтрокиУровня[0];
		ДанныеПеремещения.Вставить("ИмяЭлементаМесторасположения", ПервыеДанные.Имя);

		ДанныеПеремещения.Вставить("ИмяПеремещаемогоЭлемента", ТекущиеДанные.Имя);

		МенеджерПрототипов.ПереместитьЭлементУправления(ДанныеПеремещения);

		КоличествоЭлементов = ВсегоСтрокУровня * -1;
		СтрокиУровня.Сдвинуть(ИндексТекущейСтроки, КоличествоЭлементов);

	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура УдалитьФормуЭлементУправления(Команда)

	ВыполнитьУдалениеФормыИлиЭлементаУправления();

КонецПроцедуры

&НаКлиенте
Процедура СохранитьСвойстваВФайл(Команда)
	Результат = СохранитьСвойстваВФайлНаСервере();
	МенеджерФайлов.СохранитьФайл(Результат.ПутьКФайлу, Результат.Адрес, Ложь);

КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьСвойстваИзФайла(Команда)

	ВыполнитьЗагрузкуСвойствИзФайла();

КонецПроцедуры

&НаКлиенте
Процедура РедактироватьРоли(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	ПараметрыФормыРолей = Новый Структура;
	ПараметрыФормыРолей.Вставить("РежимРедактированияРолей", Истина);
	ПараметрыФормыРолей.Вставить("ТекущаяРоль", ДанныеВыбора);

	ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("РедактироватьРолиЗавершение", ЭтотОбъект);
	ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.Роли",
				 ПараметрыФормыРолей,
				 Элементы.Роль,
				 ,
				 ,
				 ,
				 ОписаниеОповещенияОЗакрытии,
				 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

КонецПроцедуры

&НаКлиенте
Процедура НастройкиИнструмента(Команда)
	//Группировки, сортировки, отборы, поиски

	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("РежимРедактированияСвойств", РежимРедактированияСвойств);
	ПараметрыФормы.Вставить("ЗагружатьСвойстваИзФайла", ЗагружатьСвойстваИзФайла);
	ПараметрыФормы.Вставить("АктивироватьТекущийЭлементВПрототипе", АктивироватьТекущийЭлементВПрототипе);

	ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("ПослеИзмененияНастроекИнструмента", ЭтотОбъект);
	ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.НастройкиИнструмента",
				 ПараметрыФормы,
				 ЭтаФорма,
				 ,
				 ,
				 ,
				 ОписаниеОповещенияОЗакрытии,
				 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

КонецПроцедуры

#Область Обработчики_добавления_элементов_управления

&НаКлиенте
Процедура ДобавитьГруппу(Команда)

	НовыйЭлементУправления(Типы.ГруппаФормы, Виды.ОбычнаяГруппа);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьКоманднуюПанель(Команда)

	НовыйЭлементУправления(Типы.ГруппаФормы, Виды.КоманднаяПанель);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьПодменю(Команда)

	НовыйЭлементУправления(Типы.ГруппаФормы, Виды.Подменю);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьСтраницы(Команда)

	НовыйЭлементУправления(Типы.ГруппаФормы, Виды.Страницы);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьСтраницу(Команда)

	НовыйЭлементУправления(Типы.ГруппаФормы, Виды.Страница);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьКнопку(Команда)

	НовыйЭлементУправления(Типы.КнопкаФормы, Виды.ОбычнаяКнопка);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьКнопкуКоманднойПанели(Команда)

	НовыйЭлементУправления(Типы.КнопкаФормы, Виды.КнопкаКоманднойПанели);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьГиперссылку(Команда)

	НовыйЭлементУправления(Типы.КнопкаФормы, Виды.Гиперссылка);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьГиперссылкуКоманднойПанели(Команда)

	НовыйЭлементУправления(Типы.КнопкаФормы, Виды.ГиперссылкаКоманднойПанели);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьПоле(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеВвода);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьФлажок(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеФлажка);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьПереключатель(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеПереключателя);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьТаблицу(Команда)

	НовыйЭлементУправления(Типы.ТаблицаФормы, , ТипыЗначения.ТаблицаЗначений);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьДерево(Команда)

	НовыйЭлементУправления(Типы.ТаблицаФормы, , ТипыЗначения.ДеревоЗначений);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьКолонку(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеВвода);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьГруппуКолонок(Команда)

	НовыйЭлементУправления(Типы.ГруппаФормы, Виды.ГруппаКолонок);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьКонтекстноеМеню(Команда)

	НовыйЭлементУправления(Типы.ГруппаФормы, Виды.КонтекстноеМеню);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьНадпись(Команда)

	НовыйЭлементУправления(Типы.ДекорацияФормы, Виды.Надпись);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьКартинку(Команда)
	
	//НовыйЭлементУправления(Типы.ДекорацияФормы, Виды.Картинка);
	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеКартинки);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьИндикатор(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеИндикатора);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьПолосуРегулирования(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеПолосыРегулирования);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьКалендарь(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеКалендаря);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьФорматированныйДокумент(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеФорматированногоДокумента);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьФорматированнуюСтроку(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеНадписи);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьТекстовыйДокумент(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеТекстовогоДокумента);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьТабличныйДокумент(Команда)

	НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеТабличногоДокумента);

КонецПроцедуры

&НаКлиенте
Процедура ДобавитьГруппуКнопок(Команда)

	НовыйЭлементУправления(Типы.ГруппаФормы, Виды.ГруппаКнопок);

КонецПроцедуры

#КонецОбласти


&НаКлиенте
Процедура НовыйФайлДанныхИнструмента(Команда)
	ФормыИЭлементыУправления.ПолучитьЭлементы().Очистить();
	Модифицированность = Ложь;
	МенеджерПрототипов.ЗакрытьВсеФормы();
	МенеджерПрототипов.Инициализировать();
	ИмяФайлаДанныхИнструмента = "";
	УстановитьЗаголовок();	
КонецПроцедуры

&НаКлиенте
Процедура ОткрытьФайлДанныхИнструмента(Команда)
	УИ_ОбщегоНазначенияКлиент.ПрочитатьДанныеКонсолиИзФайла("РедакторПрототиповФорм", СтруктураОписанияСохраняемогоФайла(),
		Новый ОписаниеОповещения("ОткрытьФайлЗавершение", ЭтотОбъект));
КонецПроцедуры

&НаКлиенте
Процедура СохранитьФайлДанныхИнструмента(Команда)
	СохранитьФайлНаДиск();
КонецПроцедуры

&НаКлиенте
Процедура СохранитьФайлДанныхИнструментаКак(Команда)
	СохранитьФайлНаДиск(Истина);
КонецПроцедуры

//@skip-warning
&НаКлиенте
Процедура Подключаемый_ВыполнитьОбщуюКомандуИнструментов(Команда) 
	УИ_ОбщегоНазначенияКлиент.Подключаемый_ВыполнитьОбщуюКомандуИнструментов(ЭтотОбъект, Команда);
КонецПроцедуры


#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервере
Процедура ЗагрузитьРеквизитыИзМакетов()

	ДобавляемыеРеквизиты = Новый Массив;

	Имена = Новый Массив;
	Имена.Добавить("ФормыИЭлементыУправления");
	Имена.Добавить("СвойстваФормИЭлементовУправления");

	Для Каждого Имя Из Имена Цикл
		Реквизиты = РеквизитыОписаниеФормИЭлементовУправления(Имя);
		Для Каждого Реквизит Из Реквизиты Цикл
			НовыйРеквизит = Новый РеквизитФормы(Реквизит.Имя, Новый ОписаниеТипов(Реквизит.ТипыЗначения), Имя);
			ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
		КонецЦикла;
	КонецЦикла;

	ИзменитьРеквизиты(ДобавляемыеРеквизиты);

КонецПроцедуры

&НаСервере
Процедура ЗагрузитьЭлементыУправленияИзМакетов()

	Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("СвойстваФормИЭлементовУправленияЭлементы");
	Область = Макет.ПолучитьОбласть("Строки");
	Для НомерСтроки = 1 По Область.ВысотаТаблицы Цикл
		Имя = Область.Область(НомерСтроки, 1).Текст;
		Вид = Область.Область(НомерСтроки, 2).Текст;
		ЗаголовокПоля = Область.Область(НомерСтроки, 3).Текст;
		ОбработчикСобытия = Область.Область(НомерСтроки, 4).Текст;
		ИмяРодителя = Область.Область(НомерСтроки, 5).Текст;
		Если ПустаяСтрока(ИмяРодителя) Тогда
			ИмяРодителя = "СвойстваФормИЭлементовУправления";
		КонецЕсли;
		ГиперссылкаЯчейки = Не ПустаяСтрока(Область.Область(НомерСтроки, 6).Текст);

		НовыйЭлемент = ЭтаФорма.Элементы.Добавить(Имя, Тип("ПолеФормы"), Элементы[ИмяРодителя]);
		НовыйЭлемент.Вид = ВидПоляФормы[Вид];
		НовыйЭлемент.ПутьКДанным = СтрШаблон("%1.%2", "СвойстваФормИЭлементовУправления", Имя);
		НовыйЭлемент.Заголовок = ЗаголовокПоля;
		НовыйЭлемент.УстановитьДействие("ПриИзменении", ОбработчикСобытия);
		НовыйЭлемент.ГиперссылкаЯчейки = ГиперссылкаЯчейки;
	КонецЦикла;

КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьНаборыЗначений()

	НаборыЗначений = МенеджерНаборовЗначений.НаборыЗначений();
	Типы = НаборыЗначений.Типы;
	Виды = НаборыЗначений.Виды;
	ТипыЗначения = НаборыЗначений.ТипыЗначения;
	ВариантыЗаполнения = НаборыЗначений.ВариантыЗаполнения;

КонецПроцедуры

&НаСервере
Функция РеквизитыОписаниеФормИЭлементовУправления(ИмяМакета)

	Результат = Новый Массив;

	Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет(ИмяМакета);
	Область = Макет.ПолучитьОбласть("Строки");
	Для НомерСтроки = 1 По Область.ВысотаТаблицы Цикл
		ДанныеСтроки = Новый Структура;
		ДанныеСтроки.Вставить("Имя", Область.Область(НомерСтроки, 1).Текст);

		ТипЗначения = Область.Область(НомерСтроки, 2).Текст;
		Если Найти(ТипЗначения, ",") > 0 Тогда
			ДанныеСтроки.Вставить("ТипыЗначения", РазложитьСтрокуВМассивПодстрок(ТипЗначения, ",", , Истина));
		Иначе
			ДанныеСтроки.Вставить("ТипыЗначения", ТипЗначения);
		КонецЕсли;

		Результат.Добавить(ДанныеСтроки);
	КонецЦикла;

	Возврат Результат;

КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция РазложитьСтрокуВМассивПодстрок(Знач Значение, Знач Разделитель = ",", Знач ПропускатьПустыеСтроки = Неопределено,
	СокращатьНепечатаемыеСимволы = Ложь)

	Если Разделитель = "," И ПропускатьПустыеСтроки = Неопределено И СокращатьНепечатаемыеСимволы Тогда

		Результат = СтрРазделить(Значение, ",", Ложь);
		Для Индекс = 0 По Результат.ВГраница() Цикл
			Результат[Индекс] = СокрЛП(Результат[Индекс]);
		КонецЦикла
		;
		Возврат Результат;

	КонецЕсли;

	Результат = Новый Массив;
	
	// Для обеспечения обратной совместимости.
	Если ПропускатьПустыеСтроки = Неопределено Тогда
		ПропускатьПустыеСтроки = ?(Разделитель = " ", Истина, Ложь);
		Если ПустаяСтрока(Значение) Тогда
			Если Разделитель = " " Тогда
				Результат.Добавить("");
			КонецЕсли;
			Возврат Результат;
		КонецЕсли;
	КонецЕсли;
	//

	Позиция = СтрНайти(Значение, Разделитель);
	Пока Позиция > 0 Цикл
		Подстрока = Лев(Значение, Позиция - 1);
		Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Подстрока) Тогда
			Если СокращатьНепечатаемыеСимволы Тогда
				Результат.Добавить(СокрЛП(Подстрока));
			Иначе
				Результат.Добавить(Подстрока);
			КонецЕсли;
		КонецЕсли;
		Значение = Сред(Значение, Позиция + СтрДлина(Разделитель));
		Позиция = СтрНайти(Значение, Разделитель);
	КонецЦикла;

	Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Значение) Тогда
		Если СокращатьНепечатаемыеСимволы Тогда
			Результат.Добавить(СокрЛП(Значение));
		Иначе
			Результат.Добавить(Значение);
		КонецЕсли;
	КонецЕсли;

	Возврат Результат;

КонецФункции

&НаКлиенте
Функция ВерсияПлатформыСтаршеИлиРавнаТребуемойВерсии(Знач ТребуемаяВерсия)

	Результат = Истина;

	СистемнаяИнформация = Новый СистемнаяИнформация;
	ВерсияПлатформы = СистемнаяИнформация.ВерсияПриложения;

	КоличествоИтераций = 0;
	Пока Не КоличествоИтераций = 3 Цикл
		НомерПлатформы = Число(Лев(ВерсияПлатформы, Найти(ВерсияПлатформы, ".") - 1));
		НомерТребуемой = Число(Лев(ТребуемаяВерсия, Найти(ТребуемаяВерсия, ".") - 1));

		Если НомерПлатформы < НомерТребуемой Тогда
			Результат = Ложь;
			Прервать;
		КонецЕсли;

		ВерсияПлатформы = Сред(ВерсияПлатформы, Найти(ВерсияПлатформы, ".") + 1);
		ТребуемаяВерсия = Сред(ТребуемаяВерсия, Найти(ТребуемаяВерсия, ".") + 1);

		КоличествоИтераций = КоличествоИтераций + 1;
	КонецЦикла;

	Возврат Результат;

КонецФункции

&НаКлиенте
Процедура ИнициализироватьМенеджераПрототипов()

	МенеджерПрототипов = ПолучитьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.МенеджерПрототипов");
	МенеджерПрототипов.Инициализировать();

КонецПроцедуры

&НаКлиенте
Процедура ИнициализироватьМенеджераФайлов()

	Если ВерсияПлатформыСтаршеИлиРавнаТребуемойВерсии("8.3.15.0") Тогда
		МенеджерФайлов = ПолучитьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.МенеджерФайлов_8_3_15");
	ИначеЕсли ВерсияПлатформыСтаршеИлиРавнаТребуемойВерсии("8.3.6.0") Тогда
		МенеджерФайлов = ПолучитьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.МенеджерФайлов_8_3_6");
	Иначе
		ВызватьИсключение "Не удалось инициализировать менеджера файлов. Эскиз работает с версиями платформы от 8.3.6";
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ИнициализироватьМенеджераНаборовЗначений()

	МенеджерНаборовЗначений = ПолучитьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.МенеджерНаборовЗначений");

КонецПроцедуры

&НаСервере
Процедура ФормыИЭлементыУправленияИзМассиваРекурсивно(Строки, Родитель, ПервыйУровень, Замена, РасположениеФайла)

	Для Каждого Строка Из Строки Цикл
		Если ПервыйУровень Тогда
			ИскомаяСтрока = Родитель.Найти(Строка.Идентификатор, "Идентификатор");
			Если Не ИскомаяСтрока = Неопределено Тогда
				Замена = Истина;
				Родитель.Удалить(ИскомаяСтрока);
			КонецЕсли;
		КонецЕсли;
		НоваяСтрока = Родитель.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
		МассивСтруктурВСписокЗначений(НоваяСтрока, Строка.СписокВыбора);
		НоваяСтрока.РасположениеФайла = РасположениеФайла;

		ДочерниеСтроки = Строка.Элементы;
		Если ДочерниеСтроки.Количество() Тогда
			ФормыИЭлементыУправленияИзМассиваРекурсивно(ДочерниеСтроки, НоваяСтрока.Строки, Ложь, Замена, "");
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьПрототипРекурсивно(Строки)

	Для Каждого Строка Из Строки Цикл
		Если Строка.Тип = Типы.ФормаКлиентскогоПриложения Тогда
			МенеджерПрототипов.ОткрытьПрототип(Строка, ЭтаФорма, Ложь);
			ПодготовитьСчетчики(Строка.Идентификатор);
		Иначе
			Связать = Ложь;
			Если Строка.Тип = Типы.ПолеФормы Или Строка.Тип = Типы.КнопкаФормы Или Строка.Тип = Типы.ТаблицаФормы Тогда

				Связать = Истина;
			КонецЕсли;

			КлючиСпециальныеСвойства = ПолучитьКлючиСпециальныеСвойства();
			СпециальныеСвойства = Новый Структура(КлючиСпециальныеСвойства);
			ЗаполнитьЗначенияСвойств(СпециальныеСвойства, Строка);
			СпециальныеСвойства.Идентификатор = Строка.Прототип;

			КлючиТиповыхСвойств = ПолучитьКлючиТиповыхСвойств(Строка, КлючиСпециальныеСвойства);
			ТиповыеСвойства = Новый Структура(КлючиТиповыхСвойств);
			ЗаполнитьЗначенияСвойств(ТиповыеСвойства, Строка);

			МенеджерПрототипов.ДобавитьЭлементУправления(СпециальныеСвойства, ТиповыеСвойства, Связать, Ложь);
			НовоеИмяЭлементаУправления(Строка.Прототип, Строка.Вид, Строка.Тип);
		КонецЕсли
		;

		ДочерниеСтроки = Строка.ПолучитьЭлементы();
		Если ДочерниеСтроки.Количество() Тогда
			ЗагрузитьПрототипРекурсивно(ДочерниеСтроки);
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры

&НаСервере
Функция ФормыИЭлементыУправленияВМассивРекурсивно(Строки, Ключи, ИсключаемыеСвойства)

	Результат = Новый Массив;

	Для Каждого Строка Из Строки Цикл
		ДанныеСтроки = Новый Структура(Ключи);
		ЗаполнитьЗначенияСвойств(ДанныеСтроки, Строка, , ИсключаемыеСвойства);

		ДочерниеСтроки = Строка.Строки;
		Если ДочерниеСтроки.Количество() Тогда
			ДанныеСтроки.Элементы = ФормыИЭлементыУправленияВМассивРекурсивно(ДочерниеСтроки, Ключи, "");
		Иначе
			ДанныеСтроки.Элементы = Новый Массив;
		КонецЕсли;

		Результат.Добавить(ДанныеСтроки);

	КонецЦикла;

	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура РедактироватьРолиЗавершение(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
	Если РезультатЗакрытия = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Элементы.Роль.СписокВыбора.ЗагрузитьЗначения(РезультатЗакрытия.ВыгрузитьЗначения());

КонецПроцедуры

&НаКлиенте
Процедура ПослеИзмененияНастроекИнструмента(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
	Если ЗначениеЗаполнено(РезультатЗакрытия) Тогда
		ЗаполнитьЗначенияСвойств(ЭтотОбъект, РезультатЗакрытия);
		ОбработатьИзменениеНастроекПроекта();

	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьИзменениеНастроекПроекта()

	Элементы.ГруппаКолонокРежимРедактированияСвойств.Видимость = РежимРедактированияСвойств;
	Элементы.ГруппаКнопокРежимРедактированияСвойств.Видимость = РежимРедактированияСвойств;

	Если РежимРедактированияСвойств Тогда
		Элементы.СвойстваФормИЭлементовУправления.ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиЭлементаФормы.Авто;
		Элементы.Свойство.Видимость = Истина;
		Элементы.СвойстваФормИЭлементовУправления.ОтборСтрок = Неопределено;
	Иначе
		Элементы.СвойстваФормИЭлементовУправления.ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиЭлементаФормы.Нет;
		Элементы.Свойство.Видимость = Ложь;
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Функция ПолучитьСтрокуПрототипаРекурсивно(Элемент)

	Результат = "";

	Родитель = Элемент.ПолучитьРодителя();
	Если Родитель = Неопределено Тогда
		Результат = Элемент;
	Иначе
		Результат = ПолучитьСтрокуПрототипаРекурсивно(Родитель);
	КонецЕсли;

	Возврат Результат;

КонецФункции
&НаКлиенте
Функция ЭтоКолонка(Элемент)

	Результат = Ложь;

	Если Элемент <> Неопределено Тогда
		Если Элемент.Тип = Типы.ТаблицаФормы Тогда
			Результат = Истина;
			;
		Иначе
			Родитель = Элемент.ПолучитьРодителя();
			Результат = ЭтоКолонка(Родитель);
		КонецЕсли;
	КонецЕсли;

	Возврат Результат;

КонецФункции

&НаКлиенте
Процедура АктивизироватьТекущийЭлемент() Экспорт

	Если Не АктивироватьТекущийЭлементВПрототипе Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если ТекущиеДанные.Тип = Типы.ФормаКлиентскогоПриложения Тогда
		// Активизировать форму
	Иначе
		СтрокаПрототипа = ПолучитьСтрокуПрототипаРекурсивно(ТекущиеДанные);
		МенеджерПрототипов.АктивизироватьТекущийЭлемент(СтрокаПрототипа.Идентификатор, ТекущиеДанные.Имя);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Функция ПолучитьПараметрыОтбораСвойств(ТекущиеДанные)
	КлючОтбора = "Отбор_";

	ПараметрыОтбора = Новый Структура;
	Если ТекущиеДанные = Неопределено Тогда
		КлючОтбора = КлючОтбора + "Пусто";

	ИначеЕсли ТекущиеДанные.Тип = Типы.ФормаКлиентскогоПриложения Тогда
		КлючОтбора = КлючОтбора + ТекущиеДанные.Тип;

	ИначеЕсли ТекущиеДанные.Тип = Типы.ТаблицаФормы Тогда
		КлючОтбора = КлючОтбора + ТекущиеДанные.Тип + "_";
		КлючОтбора = КлючОтбора + ТекущиеДанные.ТипЗначения;

	ИначеЕсли Истина И ТекущиеДанные.Тип = Типы.ПолеФормы И ТекущиеДанные.Вид = Виды.ПолеВвода Тогда

		КлючОтбора = КлючОтбора + ТекущиеДанные.Тип + "_";
		КлючОтбора = КлючОтбора + ТекущиеДанные.Вид + "_";
		КлючОтбора = КлючОтбора + ТекущиеДанные.ТипЗначения;

	Иначе
		КлючОтбора = КлючОтбора + ТекущиеДанные.Тип + "_";
		КлючОтбора = КлючОтбора + ТекущиеДанные.Вид;

	КонецЕсли;

	ПараметрыОтбора.Вставить(КлючОтбора, Истина);

	Возврат ПараметрыОтбора;
КонецФункции

&НаКлиенте
Процедура ОпределитьСвойства() Экспорт
	Если РежимРедактированияСвойств Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;

	ПараметрыОтбора = ПолучитьПараметрыОтбораСвойств(ТекущиеДанные);
	Элементы.СвойстваФормИЭлементовУправления.ОтборСтрок = Новый ФиксированнаяСтруктура(ПараметрыОтбора);

	ИскомыеСтроки = СвойстваФормИЭлементовУправления.НайтиСтроки(ПараметрыОтбора);
	Для Каждого Строка Из ИскомыеСтроки Цикл
		Строка.Значение = ТекущиеДанные[Строка.Свойство];
		Если Строка.ВариантЗаполнения = ВариантыЗаполнения.ВыборИзВыпадающегоСписка Тогда
			ИскомоеЗначение = Строка.Значение;
			Если ТипЗнч(ИскомоеЗначение) = Тип("Булево") Тогда
				ИскомоеЗначение = Формат(ИскомоеЗначение, "БЛ=Нет; БИ=Да");

			КонецЕсли;

			ИмяДанныхВыбора = ПолучитьИмяДанныхВыбора(Строка.Свойство, ТекущиеДанные.Тип, ТекущиеДанные.Вид);
			ИскомыйЭлемент = Строка[ИмяДанныхВыбора].НайтиПоЗначению(ИскомоеЗначение);
			Если ИскомыйЭлемент <> Неопределено Тогда
				Строка.ЗначениеПредставление = ИскомыйЭлемент.Представление;
			КонецЕсли;
		Иначе
			ОбновитьПредставлениеЗначенияСвойства(Строка);
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ОпределитьГруппуКоманд()

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Элементы.ГруппаКоманды.Видимость = Ложь;
	Иначе
		Элементы.ГруппаКоманды.Видимость = Истина;

		Элементы.ГруппаКоманды.ТекущаяСтраница = Элементы.ГруппаКоманды_Все;
		Если ТекущиеДанные.Тип = Типы.ГруппаФормы Тогда
			Если ТекущиеДанные.Вид = Виды.Страницы Тогда
				Элементы.ГруппаКоманды.ТекущаяСтраница = Элементы.ГруппаКоманды_Страницы;
			ИначеЕсли ТекущиеДанные.Вид = Виды.КоманднаяПанель
					  Или ТекущиеДанные.Вид = Виды.Подменю
					  Или ТекущиеДанные.Вид = Виды.ГруппаКнопок
					  Или ТекущиеДанные.Вид = Виды.КонтекстноеМеню Тогда

				Элементы.ГруппаКоманды.ТекущаяСтраница = Элементы.ГруппаКоманды_КоманднаяПанель;
			ИначеЕсли ТекущиеДанные.Вид = Виды.ГруппаКолонок Тогда
				Элементы.ГруппаКоманды.ТекущаяСтраница = Элементы.ГруппаКоманды_Таблица;
			КонецЕсли;
		ИначеЕсли ТекущиеДанные.Тип = Типы.ТаблицаФормы Тогда
			Элементы.ГруппаКоманды.ТекущаяСтраница = Элементы.ГруппаКоманды_Таблица;
		ИначеЕсли ТекущиеДанные.Тип = Типы.КнопкаФормы Тогда
			Родитель = ТекущиеДанные.ПолучитьРодителя();
			Если Родитель.Вид = Виды.КоманднаяПанель
				 Или Родитель.Вид = Виды.Подменю
				 Или Родитель.Вид = Виды.ГруппаКнопок
				 Или Родитель.Вид = Виды.КонтекстноеМеню Тогда

				Элементы.ГруппаКоманды.ТекущаяСтраница = Элементы.ГруппаКоманды_КоманднаяПанель;
			КонецЕсли;
		ИначеЕсли ТекущиеДанные.Тип = Типы.ПолеФормы Тогда
			Родитель = ТекущиеДанные.ПолучитьРодителя();
			Если Родитель.Тип = Типы.ТаблицаФормы Или Родитель.Вид = Виды.ГруппаКолонок Тогда

				Элементы.ГруппаКоманды.ТекущаяСтраница = Элементы.ГруппаКоманды_Таблица;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура СкрытьВсеСтраницыКромеТекущей()

	ТекущаяСтраница = Элементы.ГруппаКоманды.ТекущаяСтраница;
	Страницы = Элементы.ГруппаКоманды.ПодчиненныеЭлементы;
	Для Каждого Страница Из Страницы Цикл
		Страница.Видимость = Страница = ТекущаяСтраница;
	КонецЦикла;

КонецПроцедуры

&НаКлиенте
Процедура ОбработатьИзменениеСвойства()

	ТекущиеДанныеПрототип = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанныеПрототип = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанныеСвойств = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;
	Если ТекущиеДанныеСвойств = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанныеПрототип[ТекущиеДанныеСвойств.Свойство] = ТекущиеДанныеСвойств.Значение;
	ОбновитьПредставлениеЗначенияСвойства(ТекущиеДанныеСвойств);

	Если ТекущиеДанныеПрототип.Тип = Типы.ФормаКлиентскогоПриложения Тогда
		СтрокаПрототипа = ТекущиеДанныеПрототип;
		МенеджерПрототипов.ИзменитьСвойство(ТекущиеДанныеПрототип.Идентификатор,
											ТекущиеДанныеСвойств.Свойство,
											ТекущиеДанныеСвойств.Значение);
	Иначе
		СтрокаПрототипа = ПолучитьСтрокуПрототипаРекурсивно(ТекущиеДанныеПрототип);
		Если ТекущиеДанныеСвойств.Свойство = "ТипЗначения"
			 Или ТекущиеДанныеСвойств.Свойство = "СоставДаты"
			 Или ТекущиеДанныеСвойств.Свойство = "Длина"
			 Или ТекущиеДанныеСвойств.Свойство = "Точность" Тогда

			КлючиСпециальныеСвойства = ПолучитьКлючиСпециальныеСвойства();
			СпециальныеСвойства = Новый Структура(КлючиСпециальныеСвойства);
			ЗаполнитьЗначенияСвойств(СпециальныеСвойства, ТекущиеДанныеПрототип);

			МенеджерПрототипов.СоздатьИзменитьРеквизит(СтрокаПрототипа.Идентификатор, СпециальныеСвойства);
		Иначе
			МенеджерПрототипов.ИзменитьСвойство(СтрокаПрототипа.Идентификатор,
												ТекущиеДанныеСвойств.Свойство,
												ТекущиеДанныеСвойств.Значение,
												Ложь,
												ТекущиеДанныеПрототип.Имя);
			Если ТекущиеДанныеСвойств.Свойство = "КнопкаПоУмолчанию" И ТекущиеДанныеСвойств.Значение = "Да" Тогда
				СтрокаПрототипа.КнопкаПоУмолчанию = ТекущиеДанныеПрототип.Идентификатор;
				ПодключитьОбработчикОжидания("ОтменитьПредыдущуюКнопкуПоУмолчанию", 0.1, Истина);
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;

	СтрокаПрототипа.Модифицированность = Истина;
	СтрокаПрототипа.ИндексКартинки = ИндексКартинкиФормы(Истина);

КонецПроцедуры

&НаКлиенте
Процедура ОтменитьПредыдущуюКнопкуПоУмолчанию() Экспорт
	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Прототип = ПолучитьСтрокуПрототипаРекурсивно(ТекущиеДанные);
	ОтменитьПредыдущуюКнопкуПоУмолчаниюРекурсивно(Прототип.КнопкаПоУмолчанию, Прототип.ПолучитьЭлементы());
КонецПроцедуры

&НаКлиенте
Процедура ОтменитьПредыдущуюКнопкуПоУмолчаниюРекурсивно(ИмяИскомойКнопки, Строки)
	Для Каждого Строка Из Строки Цикл
		Если Истина И Строка.КнопкаПоУмолчанию = "Да" И Строка.Имя <> ИмяИскомойКнопки Тогда

			Строка.КнопкаПоУмолчанию = Ложь;

		Иначе
			ОтменитьПредыдущуюКнопкуПоУмолчаниюРекурсивно(ИмяИскомойКнопки, Строка.ПолучитьЭлементы());

		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Функция ПолучитьСледующуюСтроку(ТекущиеДанные)
	Результат = Неопределено;

	Родитель = ТекущиеДанные.ПолучитьРодителя();
	Если Родитель = Неопределено Тогда
		СтрокиУровня = ФормыИЭлементыУправления.ПолучитьЭлементы();

	Иначе
		СтрокиУровня = Родитель.ПолучитьЭлементы();

	КонецЕсли;

	ВзятьСледующий = Ложь;

	Для Каждого Строка Из СтрокиУровня Цикл
		Если ВзятьСледующий Тогда
			Результат = Строка;

			Прервать;
		ИначеЕсли Строка.Имя = ТекущиеДанные.Имя Тогда
			ВзятьСледующий = Не Строка.Перемещается;

		КонецЕсли;
	КонецЦикла;

	Возврат Результат;
КонецФункции

&НаКлиенте
Функция ДобавитьСтрокуВставкой(ТекущиеДанные)
	Результат = Неопределено;

	СтрокиУровня = ТекущиеДанные.ПолучитьРодителя().ПолучитьЭлементы();
	Для Каждого Строка Из СтрокиУровня Цикл
		Если Строка.Имя = ТекущиеДанные.Имя Тогда
			ИндексВставки = СтрокиУровня.Индекс(Строка) + 1;

			Прервать;
		КонецЕсли;
	КонецЦикла;

	Результат = СтрокиУровня.Вставить(ИндексВставки);

	Возврат Результат;
КонецФункции

&НаКлиенте
Функция НовыйЭлементУправления(Тип, Вид = "", ТипЗначения = "", Источник = Неопределено, Родитель = Неопределено)

	НоваяСтрока = Неопределено;
	Перемещение = Ложь;

	ТекущиеДанные = ?(Родитель = Неопределено, Элементы.ФормыИЭлементыУправления.ТекущиеДанные, Родитель);
	
	Если ТекущиеДанные = Неопределено Тогда
		Возврат НоваяСтрока;
	ИначеЕсли ТекущиеДанные.Тип = Типы.ФормаКлиентскогоПриложения
			  Или ТекущиеДанные.Тип = Типы.ГруппаФормы
			  Или ТекущиеДанные.Тип = Типы.ТаблицаФормы Тогда

		НоваяСтрока = ТекущиеДанные.ПолучитьЭлементы().Добавить();
		Родитель = ТекущиеДанные;
	Иначе
		ИмяСледующийЭлемент = ПолучитьИмяСледующийЭлементУровня(ТекущиеДанные);
		Если Не ПустаяСтрока(ИмяСледующийЭлемент) Тогда
			Перемещение = Истина;
		КонецЕсли;

		НоваяСтрока = ДобавитьСтрокуВставкой(ТекущиеДанные);
		Родитель = ТекущиеДанные.ПолучитьРодителя();
	КонецЕсли;

	НоваяСтрока.Идентификатор = Новый УникальныйИдентификатор;
	НоваяСтрока.Тип = Тип;
	НоваяСтрока.Вид = Вид;
	НоваяСтрока.ЭтоКолонка = ЭтоКолонка(ТекущиеДанные);

	Если Родитель.Тип <> Типы.ФормаКлиентскогоПриложения Тогда
		НоваяСтрока.ИмяРодителя = Родитель.Имя;
	КонецЕсли;

	Прототип = ПолучитьСтрокуПрототипаРекурсивно(Родитель);
	Прототип.ИндексКартинки = ИндексКартинкиФормы(Истина);

	НоваяСтрока.Прототип = Прототип.Идентификатор;

	Если Источник = Неопределено Тогда
		НовоеИмя = НовоеИмяЭлементаУправления(НоваяСтрока.Прототип, Вид, Тип);
	Иначе
		НовоеИмя = Источник.Имя;
	КонецЕсли;

	Если Тип = Типы.ГруппаФормы Тогда
		Связать = Ложь;
		Если Вид = Виды.ОбычнаяГруппа Тогда
			НоваяСтрока.ИндексКартинки = 2;
		ИначеЕсли Вид = Виды.КоманднаяПанель Тогда
			НоваяСтрока.ИндексКартинки = 1;
		ИначеЕсли Вид = Виды.Страницы Тогда
			НоваяСтрока.ИндексКартинки = 19;
		ИначеЕсли Вид = Виды.Страница Тогда
			НоваяСтрока.ИндексКартинки = 18;
		ИначеЕсли Вид = Виды.Подменю Тогда
			НоваяСтрока.ИндексКартинки = 16;
		ИначеЕсли Вид = Виды.ГруппаКнопок Тогда
			НоваяСтрока.ИндексКартинки = 9;
		ИначеЕсли Вид = Виды.ГруппаКолонок Тогда
			НоваяСтрока.ИндексКартинки = 10;
		ИначеЕсли Вид = Виды.КонтекстноеМеню Тогда
			НоваяСтрока.ИндексКартинки = 27;
		КонецЕсли;
	ИначеЕсли Тип = Типы.ПолеФормы Тогда
		Связать = Истина;
		Если Вид = Виды.ПолеВвода Тогда
			Если НоваяСтрока.ЭтоКолонка Тогда
				НоваяСтрока.ИндексКартинки = 14;
				НоваяСтрока.ИмяТаблицы = ПолучитьИмяТаблицыРекурсивно(НоваяСтрока);
				НоваяСтрока.ПутьКДанным = НоваяСтрока.ИмяТаблицы + "." + НовоеИмя;
				НоваяСтрока.Путь = НоваяСтрока.ИмяТаблицы;
				НоваяСтрока.ТипЗначения = "Строка";
			Иначе
				НоваяСтрока.ИндексКартинки = 3;
				НоваяСтрока.ПутьКДанным = НовоеИмя;
				НоваяСтрока.Путь = "";
				НоваяСтрока.ТипЗначения = "Строка";
			КонецЕсли;
		ИначеЕсли Вид = Виды.ПолеФорматированногоДокумента Тогда
			НоваяСтрока.ИндексКартинки = 23;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.Путь = "";
			НоваяСтрока.ТипЗначения = "ФорматированныйДокумент";
			НоваяСтрока.Ширина = 50;
			НоваяСтрока.Высота = 10;
		ИначеЕсли Вид = Виды.ПолеНадписи Тогда
			Если НоваяСтрока.ЭтоКолонка Тогда
				НоваяСтрока.ИндексКартинки = 14; // TODO: для колонки с видом Надпись нужна свой картинка
				НоваяСтрока.ИмяТаблицы = ПолучитьИмяТаблицыРекурсивно(НоваяСтрока);
				НоваяСтрока.ПутьКДанным = НоваяСтрока.ИмяТаблицы + "." + НовоеИмя;
				НоваяСтрока.Путь = НоваяСтрока.ИмяТаблицы;
				НоваяСтрока.ТипЗначения = "Строка";
			Иначе
				// Только для форматированной строки, остальное - Надпись.
				НоваяСтрока.ИндексКартинки = 26;
				НоваяСтрока.ПутьКДанным = НовоеИмя;
				НоваяСтрока.Путь = "";
				НоваяСтрока.ТипЗначения = "ФорматированнаяСтрока";
			КонецЕсли;
		ИначеЕсли Вид = Виды.ПолеТекстовогоДокумента Тогда
			НоваяСтрока.ИндексКартинки = 24;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.Путь = "";
			НоваяСтрока.ТипЗначения = "ТекстовыйДокумент";
			НоваяСтрока.Ширина = 50;
			НоваяСтрока.Высота = 10;
		ИначеЕсли Вид = Виды.ПолеТабличногоДокумента Тогда
			НоваяСтрока.ИндексКартинки = 25;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.Путь = "";
			НоваяСтрока.ТипЗначения = "ТабличныйДокумент";
			НоваяСтрока.Ширина = 50;
			НоваяСтрока.Высота = 10;
		ИначеЕсли Вид = Виды.ПолеФлажка Тогда
			НоваяСтрока.ИндексКартинки = 20;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.ТипЗначения = "Булево";
		ИначеЕсли Вид = Виды.ПолеПереключателя Тогда
			НоваяСтрока.ИндексКартинки = 15;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.ТипЗначения = "Строка";
			НоваяСтрока.СписокВыбора = Новый СписокЗначений;
		ИначеЕсли Вид = Виды.ПолеИндикатора Тогда
			НоваяСтрока.ИндексКартинки = 11;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.ТипЗначения = "Число";
			НоваяСтрока.Ширина = 20;
			НоваяСтрока.Высота = 1;
		ИначеЕсли Вид = Виды.ПолеПолосыРегулирования Тогда
			НоваяСтрока.ИндексКартинки = 17;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.ТипЗначения = "Число";
			НоваяСтрока.Ширина = 20;
			НоваяСтрока.Высота = 1;
		ИначеЕсли Вид = Виды.ПолеКалендаря Тогда
			НоваяСтрока.ИндексКартинки = 12;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.ТипЗначения = "Дата";
			НоваяСтрока.Ширина = 20;
			НоваяСтрока.Высота = 1;
		ИначеЕсли Вид = Виды.ПолеКартинки Тогда
			НоваяСтрока.ИндексКартинки = 13;
			НоваяСтрока.ПутьКДанным = НовоеИмя;
			НоваяСтрока.ТипЗначения = "Число";
		КонецЕсли;
	ИначеЕсли Тип = Типы.КнопкаФормы Тогда
		Связать = Истина;
		Если Вид = Виды.ОбычнаяКнопка Тогда
			НоваяСтрока.ИндексКартинки = 4;
		ИначеЕсли Вид = Виды.КнопкаКоманднойПанели Тогда
			НоваяСтрока.ИндексКартинки = 4;
		ИначеЕсли Вид = Виды.Гиперссылка Тогда
			НоваяСтрока.ИндексКартинки = 21;
		ИначеЕсли Вид = Виды.ГиперссылкаКоманднойПанели Тогда
			НоваяСтрока.ИндексКартинки = 21;
		КонецЕсли;
	ИначеЕсли Тип = Типы.ТаблицаФормы Тогда
		Связать = Истина;
		Если ТипЗначения = ТипыЗначения.ТаблицаЗначений Тогда
			НоваяСтрока.ИндексКартинки = 7;
			НоваяСтрока.ТипЗначения = ТипЗначения;
		ИначеЕсли ТипЗначения = ТипыЗначения.ДеревоЗначений Тогда
			НоваяСтрока.ИндексКартинки = 8;
			НоваяСтрока.ТипЗначения = ТипЗначения;
		КонецЕсли;
	ИначеЕсли Тип = Типы.ДекорацияФормы Тогда
		Связать = Ложь;
		Если Вид = Виды.Надпись Тогда
			НоваяСтрока.ИндексКартинки = 5;
		ИначеЕсли Вид = Виды.Картинка Тогда
			НоваяСтрока.ИндексКартинки = 13;
		КонецЕсли;
	КонецЕсли;

	НоваяСтрока.Имя = НовоеИмя;
	НоваяСтрока.Заголовок = НовоеИмя;

	Если Источник = Неопределено Тогда
		ЗаполнитьСвойстваПервымЗначениемДанныхВыбора(НоваяСтрока);
		ЗаполнитьСвойствоПервымЗначениемДанныхВыбора(НоваяСтрока, "СоставДаты");
	Иначе
		ЗаполнитьСвойстваИзИсточника(НоваяСтрока, Источник);
	КонецЕсли;

	КлючиСпециальныеСвойства = ПолучитьКлючиСпециальныеСвойства();
	СпециальныеСвойства = Новый Структура(КлючиСпециальныеСвойства);
	ЗаполнитьЗначенияСвойств(СпециальныеСвойства, НоваяСтрока);
	СпециальныеСвойства.Идентификатор = НоваяСтрока.Прототип;

	Если Перемещение Тогда
		СпециальныеСвойства.Вставить("Элемент", ИмяСледующийЭлемент);
	КонецЕсли;

	КлючиТиповыхСвойств = ПолучитьКлючиТиповыхСвойств(НоваяСтрока, КлючиСпециальныеСвойства);
	ТиповыеСвойства = Новый Структура(КлючиТиповыхСвойств);
	ЗаполнитьЗначенияСвойств(ТиповыеСвойства, НоваяСтрока);

	МенеджерПрототипов.ДобавитьЭлементУправления(СпециальныеСвойства, ТиповыеСвойства, Связать, Перемещение);

	Элементы.ФормыИЭлементыУправления.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();

	Возврат НоваяСтрока;

КонецФункции

&НаКлиенте
Функция ПолучитьИмяТаблицыРекурсивно(ТекущаяСтрока)
	Результат = "";

	Родитель = ТекущаяСтрока.ПолучитьРодителя();
	Если Родитель.Тип = Типы.ТаблицаФормы Тогда
		Результат = Родитель.Имя;

	Иначе
		Результат = ПолучитьИмяТаблицыРекурсивно(Родитель);

	КонецЕсли;

	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура ВидимостьПодсказокКоманд(Команда)
	ОпределитьВидимостьПодсказокКоманд();

КонецПроцедуры

&НаКлиенте
Процедура НастроитьОтображениеКоманд()

	ОпределитьВидимостьПодсказокКоманд(Ложь);
	СкрытьВсеСтраницыКромеТекущей();

КонецПроцедуры

&НаКлиенте
Процедура ОпределитьВидимостьПодсказокКоманд(ЭтоИзменение = Истина)

	Если ЭтоИзменение Тогда
		ПоказыватьПодсказкиКоманд = Не ПоказыватьПодсказкиКоманд;
	КонецЕсли;

	Если ПоказыватьПодсказкиКоманд Тогда
		ВариантОтображенияПодсказки = ОтображениеПодсказки.ОтображатьСправа;
	Иначе
		ВариантОтображенияПодсказки = ОтображениеПодсказки.Всплывающая;
	КонецЕсли;

	Страницы = Элементы.ГруппаКоманды.ПодчиненныеЭлементы;
	Для Каждого Страница Из Страницы Цикл
		Для Каждого ЭлементСтраницы Из Страница.ПодчиненныеЭлементы Цикл
			Если ТипЗнч(ЭлементСтраницы) = Тип("КнопкаФормы")
				 И ЭлементСтраницы.ИмяКоманды <> "ВидимостьПодсказокКоманд" Тогда

				ЭлементСтраницы.ОтображениеПодсказки = ВариантОтображенияПодсказки;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
КонецПроцедуры

&НаСервере
Функция СохранитьСвойстваВФайлНаСервере()
	Результат = Новый Структура("Адрес,ПутьКФайлу", "", "");
	Результат.ПутьКФайлу = СтрЗаменить(РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла,
									   "Эскиз.epf",
									   "spec\Свойства.json");

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла();

	СвойстваНаСервере = РеквизитФормыВЗначение("СвойстваФормИЭлементовУправления");
	Json = СериализоватьВJSON(ТаблицаСвойствВМассивСтруктур(СвойстваНаСервере, Истина));

	Писатель = Новый ЗаписьТекста(ИмяВременногоФайла, КодировкаТекста.UTF8);
	Писатель.Записать(Json);
	Писатель.Закрыть();

	Файл = Новый Файл(ИмяВременногоФайла);
	Если Файл.Существует() Тогда
		ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
		Результат.Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
		УдалитьФайлы(ИмяВременногоФайла);
	КонецЕсли;

	Возврат Результат;
КонецФункции

&НаСервере
Функция ТаблицаСвойствВМассивСтруктур(Знач ТаблицаЗначений, ВсеКолонки, ИменаКолонок = "")
	Результат = Новый Массив;

	КолонкиИсключения = ПолучитьКолонкиИсключения();

	Если ВсеКолонки Тогда
		Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
			ТекущееИмяКолонки = Колонка.Имя;
			Если КолонкиИсключения.Найти(ТекущееИмяКолонки) <> Неопределено Тогда
				Продолжить;
			КонецЕсли;

			ИменаКолонок = ИменаКолонок + "," + ТекущееИмяКолонки;
		КонецЦикла;

		ИменаКолонок = Сред(ИменаКолонок, 2);

	КонецЕсли;

	Для Каждого Строка Из ТаблицаЗначений Цикл
		СтруктураСтроки = Новый Структура(ИменаКолонок);
		ЗаполнитьЗначенияСвойств(СтруктураСтроки, Строка);
		Результат.Добавить(СтруктураСтроки);

	КонецЦикла;

	Возврат Результат;
КонецФункции

&НаСервере
Процедура МассивСтруктурВТаблицуСвойств(ТаблицаЗначений, Свойства, ВсеКолонки, ИменаКолонок = "")
	ТаблицаЗначений.Очистить();

	КолонкиИсключения = ПолучитьКолонкиИсключения();

	Если ВсеКолонки Тогда
		Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
			ТекущееИмяКолонки = Колонка.Имя;
			Если КолонкиИсключения.Найти(ТекущееИмяКолонки) <> Неопределено Тогда
				Продолжить;
			КонецЕсли;

			ИменаКолонок = ИменаКолонок + "," + ТекущееИмяКолонки;

		КонецЦикла;

		ИменаКолонок = Сред(ИменаКолонок, 2);
	КонецЕсли;

	ИменаДанныхВыбора = ПолучитьИменаДанныхВыбора();

	Для Каждого Свойство Из Свойства Цикл
		НоваяСтрока = ТаблицаЗначений.Добавить();
		//ЗаполнитьЗначенияСвойств(НоваяСтрока, Свойство, ИменаКолонок);

		Временная = Новый Структура(ИменаКолонок);
		ЗаполнитьЗначенияСвойств(Временная, Свойство);
		ЗаполнитьЗначенияСвойств(НоваяСтрока, Временная, ИменаКолонок);

		Для Каждого ИмяДанныхВыбора Из ИменаДанныхВыбора Цикл
			Для Каждого Строка Из Свойство[ИмяДанныхВыбора] Цикл
				НоваяСтрока[ИмяДанныхВыбора].Добавить(Строка.Значение, Строка.Представление);
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
КонецПроцедуры

&НаСервере
Функция СписокЗначенийВМассивСтруктур(Список)

	Результат = Новый Массив;

	Для Каждого Строка Из Список Цикл
		ДанныеСтроки = Новый Структура;
		ДанныеСтроки.Вставить("Значение", Строка.Значение);
		ДанныеСтроки.Вставить("Представление", Строка.Представление);
		ДанныеСтроки.Вставить("Пометка", Строка.Пометка);

		Результат.Добавить(ДанныеСтроки);
	КонецЦикла;

	Возврат Результат;

КонецФункции

&НаСервере
Процедура МассивСтруктурВСписокЗначений(НоваяСтрока, Список)

	Для Каждого Строка Из Список Цикл
		НоваяСтрока.СписокВыбора.Добавить(Строка.Значение, Строка.Представление, Строка.Пометка);
	КонецЦикла;

КонецПроцедуры

&НаСервере
Функция ПолучитьКолонкиИсключения()
	Результат = Новый Массив;
	Результат.Добавить("Значение");
	Результат.Добавить("ЗначениеПредставление");

	Возврат Результат;
КонецФункции
&НаСервере
Функция СериализоватьВJSON(Значение) Экспорт
	Писатель = Новый ЗаписьJSON;
	Писатель.ПроверятьСтруктуру = Истина;

	ПараметрыПисателя = Новый ПараметрыЗаписиJSON(, Символы.Таб, , ЭкранированиеСимволовJSON.СимволыВнеBMP);
	Писатель.УстановитьСтроку(ПараметрыПисателя);

	НастройкаСериализации = Новый НастройкиСериализацииJSON;
	НастройкаСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДата;
	НастройкаСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;

	ЗаписатьJSON(Писатель, Значение, НастройкаСериализации, "Преобразователь", ЭтотОбъект);

	Результат = Писатель.Закрыть();

	Возврат Результат;
КонецФункции

&НаСервере
Функция Преобразователь(Свойство, Значение, ДополнительныеПараметры, Отказ) Экспорт

	ТипВыгружаемогоЗначения = ТипЗнч(Значение);
	Если ТипВыгружаемогоЗначения = Тип("СписокЗначений") Тогда
		Результат = СписокЗначенийВМассивСтруктур(Значение);
	Иначе
		ВызватьИсключение "Попытка выгрузить необрабатываемый тип значение, сообщите об ошибке https://github.com/alehinsasha/sketch1c/issues";
	КонецЕсли;

	Возврат Результат;
КонецФункции

&НаСервереБезКонтекста
Функция ДесериализоватьИзJSON(JSON, ИзФайла = Ложь) Экспорт

	Результат = Неопределено;

	Читатель = Новый ЧтениеJSON;
	Если ИзФайла Тогда
		Читатель.ОткрытьФайл(JSON);
	ИначеЕсли ТипЗнч(JSON) = Тип("Строка") Тогда
		Читатель.УстановитьСтроку(JSON);
	Иначе
		Читатель.ОткрытьПоток(JSON);
	КонецЕсли;

	ИменаСвойствСоЗначениемТипаДата = Новый Массив;
	Результат = ПрочитатьJSON(Читатель, , ИменаСвойствСоЗначениемТипаДата);

	Возврат Результат;

КонецФункции

&НаКлиенте
Процедура ВыполнитьЗагрузкуСвойствИзМакета()

	ВыполнитьЗагрузкуСвойствИзМакетаНаСервере();

КонецПроцедуры

&НаСервере
Процедура ВыполнитьЗагрузкуСвойствИзМакетаНаСервере()

	СвойстваФормИЭлементовУправленияНаСервере = РеквизитФормыВЗначение("СвойстваФормИЭлементовУправления");

	Json = ПолучитьJsonИзМакета("Свойства");
	Свойства = ДесериализоватьИзJSON(Json);
	МассивСтруктурВТаблицуСвойств(СвойстваФормИЭлементовУправленияНаСервере, Свойства, Истина);

	ЗначениеВРеквизитФормы(СвойстваФормИЭлементовУправленияНаСервере, "СвойстваФормИЭлементовУправления");

КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьЗагрузкуСвойствИзФайла()

	РасположениеФайлаСвойств = ПолучитьРасположениеФайлаСвойств();
	ОписаниеОповещенияОЗавершении = Новый ОписаниеОповещения("ЗагрузитьСвойстваИзФайлаЗавершение", ЭтотОбъект);
	Попытка
		МенеджерФайлов.ЗагрузитьФайл(РасположениеФайлаСвойств, Ложь, ОписаниеОповещенияОЗавершении);
	Исключение
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Файл свойств не найден. Свойства будут загружены из макета.";
		ВыполнитьЗагрузкуСвойствИзМакетаНаСервере();
	КонецПопытки;

КонецПроцедуры

&НаСервере
Функция ПолучитьJsonИзМакета(ИмяМакета)
	Результат = РеквизитФормыВЗначение("Объект").ПолучитьМакет(ИмяМакета).ПолучитьТекст();

	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура ЗагрузитьСвойстваИзФайлаЗавершение(Адрес, ДополнительныеПараметры) Экспорт
	Если Не ПустаяСтрока(Адрес) Тогда
		ЗагрузитьСвойстваИзФайлаЗавершениеНаСервере(Адрес);

	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ЗагрузитьСвойстваИзФайлаЗавершениеНаСервере(Адрес)
	ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
	ДвоичныеДанные.Записать(ИмяВременногоФайла);

	СвойстваФормИЭлементовУправленияНаСервере = РеквизитФормыВЗначение("СвойстваФормИЭлементовУправления");

	Свойства = ДесериализоватьИзJSON(ИмяВременногоФайла, Истина);
	МассивСтруктурВТаблицуСвойств(СвойстваФормИЭлементовУправленияНаСервере, Свойства, Истина);

	ЗначениеВРеквизитФормы(СвойстваФормИЭлементовУправленияНаСервере, "СвойстваФормИЭлементовУправления");

	Файл = Новый Файл(ИмяВременногоФайла);
	Если Файл.Существует() Тогда
		УдалитьФайлы(ИмяВременногоФайла);

	КонецЕсли;
КонецПроцедуры

&НаСервере
Функция ПолучитьРасположениеФайлаСвойств()
	Результат = СтрЗаменить(РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла, "Эскиз.epf", "spec\Свойства.json");

	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура РедактированиеДанныхВыбора(ИмяКолонкиДанынхВыбора)
	ТекущиеДанные = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;

	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("ДанныеВыбора", ТекущиеДанные[ИмяКолонкиДанынхВыбора]);

	ДополнительнаеПараметрыФормы = Новый Структура;
	ДополнительнаеПараметрыФормы.Вставить("ИмяКолонкиДанынхВыбора", ИмяКолонкиДанынхВыбора);

	ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("РедактированиеДанныхВыбораЗавершение", ЭтотОбъект,
		ДополнительнаеПараметрыФормы);
	ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.ДанныеВыбораСвойства",
				 ПараметрыФормы,
				 ЭтаФорма,
				 ,
				 ,
				 ,
				 ОписаниеОповещенияОЗакрытии,
				 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

КонецПроцедуры

&НаКлиенте
Процедура РедактированиеДанныхВыбораЗавершение(ДанныеВыбора, ДополнительныеПараметры) Экспорт
	Если ДанныеВыбора = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанные = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;
	ТекущиеДанные[ДополнительныеПараметры.ИмяКолонкиДанынхВыбора].Очистить();

	Для Каждого Строка Из ДанныеВыбора Цикл
		ТекущиеДанные[ДополнительныеПараметры.ИмяКолонкиДанынхВыбора].Добавить(Строка.Значение, Строка.Представление);

	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Функция ПеремещениеВозможно()
	Результат = Истина;
	
	//todo	

	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура ВыполнитьПеремещение(ПеремещаемыеЭлементы, ИдентификаторСтрокиПриемника, Перемещенные,
	Знач ПерваяИтерация = Ложь)
	СтрокаПриемник = ФормыИЭлементыУправления.НайтиПоИдентификатору(ИдентификаторСтрокиПриемника);
	ЭтоГруппа = Ложь
				Или СтрокаПриемник.Тип = Типы.ФормаКлиентскогоПриложения
				Или СтрокаПриемник.Тип = Типы.ГруппаФормы
				Или СтрокаПриемник.Тип = Типы.ТаблицаФормы;

	Родитель = СтрокаПриемник.ПолучитьРодителя();
	Если Родитель = Неопределено Тогда
		СтрокиУровня = ФормыИЭлементыУправления.ПолучитьЭлементы();

	Иначе
		СтрокиУровня = Родитель.ПолучитьЭлементы();

	КонецЕсли;

	РасположениеСтрокиПриемника = СтрокиУровня.Индекс(СтрокаПриемник) + 1;
	ЭтоПоследнийЭлементУровня = СтрокиУровня.Количество() = РасположениеСтрокиПриемника;

	Для Каждого СтрокаИсточник Из ПеремещаемыеЭлементы Цикл
		Если ТипЗнч(СтрокаИсточник) = Тип("Число") Тогда
			СтрокаИсточник = ФормыИЭлементыУправления.НайтиПоИдентификатору(СтрокаИсточник);

		КонецЕсли;

		Если ПерваяИтерация И ИерархияНеКорректна(СтрокаПриемник, СтрокаИсточник) Тогда
			Продолжить;
		КонецЕсли;

		Если Перемещенные.Найти(СтрокаИсточник.Имя) = Неопределено Тогда
			НовыйЭлемент = Неопределено;
			Если ЭтоГруппа Тогда
				НовыйЭлемент = СтрокаПриемник.ПолучитьЭлементы().Добавить();

			ИначеЕсли ЭтоПоследнийЭлементУровня Тогда
				НовыйЭлемент = СтрокиУровня.Добавить();

			Иначе
				НовыйЭлемент = СтрокиУровня.Вставить(РасположениеСтрокиПриемника);

			КонецЕсли;

			Если НовыйЭлемент <> Неопределено Тогда
				ЗаполнитьЗначенияСвойств(НовыйЭлемент, СтрокаИсточник);
				СтрокаИсточник.Перемещается = Истина;

				ПрототипИсточник = ПолучитьСтрокуПрототипаРекурсивно(СтрокаИсточник).Идентификатор;
				НовыйЭлемент.Прототип = ПолучитьСтрокуПрототипаРекурсивно(НовыйЭлемент).Идентификатор;

				Родитель = НовыйЭлемент.ПолучитьРодителя();
				Если Родитель.Тип = Типы.ФормаКлиентскогоПриложения Тогда
					НовыйЭлемент.ИмяРодителя = "";
				Иначе
					НовыйЭлемент.ИмяРодителя = Родитель.Имя;
				КонецЕсли;

				Если ПрототипИсточник = НовыйЭлемент.Прототип И ПерваяИтерация Тогда
					ДанныеПеремещения = Новый Структура;
					ДанныеПеремещения.Вставить("Идентификатор", НовыйЭлемент.Прототип);

					СледующаяСтрока = ПолучитьСледующуюСтроку(НовыйЭлемент);
					Если СледующаяСтрока = Неопределено Тогда
						ИмяЭлементаМесторасположения = "";

					Иначе
						ИмяЭлементаМесторасположения = СледующаяСтрока.Имя;

					КонецЕсли;

					ДанныеПеремещения.Вставить("ИмяЭлементаМесторасположения", ИмяЭлементаМесторасположения);
					ДанныеПеремещения.Вставить("ИмяРодительскогоЭлемента", НовыйЭлемент.ИмяРодителя);
					ДанныеПеремещения.Вставить("ИмяПеремещаемогоЭлемента", НовыйЭлемент.Имя);

					МенеджерПрототипов.ПереместитьЭлементУправления(ДанныеПеремещения);
				Иначе
					//todo
					
				КонецЕсли;

				ДочерниеЭлементы = СтрокаИсточник.ПолучитьЭлементы();
				Если ДочерниеЭлементы.Количество() Тогда
					ВыполнитьПеремещение(ДочерниеЭлементы, НовыйЭлемент.ПолучитьИдентификатор(), Перемещенные);
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Функция ИерархияНеКорректна(СтрокаПриемник, СтрокаИсточник)
	Результат = Ложь;

	Если СтрокаПриемник.Тип = Типы.ГруппаФормы И СтрокаПриемник.Вид = Виды.Страницы Тогда
		Если СтрокаИсточник.Тип = Типы.ГруппаФормы И СтрокаИсточник.Вид = Виды.Страница Тогда
			Результат = Ложь;

		Иначе
			Результат = Истина;

		КонецЕсли;
	ИначеЕсли СтрокаПриемник.Тип = Типы.ГруппаФормы И СтрокаПриемник.Вид = Виды.КоманднаяПанель Тогда
		Если СтрокаИсточник.Тип = Типы.ГруппаФормы И СтрокаИсточник.Вид = Виды.Подменю Тогда
			Результат = Ложь;

		ИначеЕсли СтрокаИсточник.Тип = Типы.ГруппаФормы И СтрокаИсточник.Вид = Виды.ГруппаКнопок Тогда
			Результат = Ложь;

		ИначеЕсли СтрокаИсточник.Тип = Типы.КнопкаФормы И СтрокаИсточник.Вид = Виды.КнопкаКоманднойПанели Тогда
			Результат = Ложь;

		ИначеЕсли СтрокаИсточник.Тип = Типы.КнопкаФормы И СтрокаИсточник.Вид = Виды.ГиперссылкаКоманднойПанели Тогда
			Результат = Ложь;

		Иначе
			Результат = Истина;

		КонецЕсли;
	ИначеЕсли СтрокаПриемник.Тип = Типы.ТаблицаФормы Тогда
		Если СтрокаИсточник.Тип = Типы.ПолеФормы И СтрокаИсточник.Вид = Виды.ПолеВвода Тогда
			Результат = Ложь;

		ИначеЕсли СтрокаИсточник.Тип = Типы.ГруппаФормы И СтрокаИсточник.Вид = Виды.ГруппаКолонок Тогда
			Результат = Ложь;

		ИначеЕсли СтрокаИсточник.Тип = Типы.ГруппаФормы И СтрокаИсточник.Вид = Виды.КонтекстноеМеню Тогда
			Результат = Ложь;

		Иначе
			Результат = Истина;

		КонецЕсли;
	КонецЕсли;

	Возврат Результат;
КонецФункции

&НаКлиенте
Функция ПолучитьИмяСледующийЭлементУровня(ТекущиеДанные)
	Результат = "";

	СтрокиУровня = ТекущиеДанные.ПолучитьРодителя().ПолучитьЭлементы();
	ИндексТекущейСтроки = СтрокиУровня.Индекс(ТекущиеДанные);
	ИндексСледующейСтроки = ИндексТекущейСтроки + 1;
	ВсегоСтрокУровня = СтрокиУровня.Количество() - 1;

	Если ИндексТекущейСтроки < ВсегоСтрокУровня Тогда
		Результат = СтрокиУровня[ИндексСледующейСтроки].Имя;

	КонецЕсли;

	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура МножественныйВводЗавершение(СписокВыбора, ДополнительныеПараметры) Экспорт

	Если СписокВыбора = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанные = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;

	ТекущиеДанные.Значение.ЗагрузитьЗначения(СписокВыбора.ВыгрузитьЗначения());
	ТекущиеДанные.ЗначениеПредставление = Строка(ТекущиеДанные.Значение);

	Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

	ОбработатьИзменениеСвойства();

КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьУдалениеФормыИлиЭлементаУправления()

	ТекущиеДанные = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если ТекущиеДанные.Тип = Типы.ФормаКлиентскогоПриложения Тогда
		МенеджерПрототипов.УдалитьФорму(ТекущиеДанные.Идентификатор);
		ФормыИЭлементыУправления.ПолучитьЭлементы().Удалить(ТекущиеДанные);
		УдалитьИзСчетчиков(ТекущиеДанные.Идентификатор);
	Иначе
		СтрокаПрототипа = ПолучитьСтрокуПрототипаРекурсивно(ТекущиеДанные);
		Если ТекущиеДанные.Тип = Типы.КнопкаФормы Тогда
			МенеджерПрототипов.УдалитьЭлементУправления(СтрокаПрототипа.Идентификатор,
														ТекущиеДанные.Имя,
														ТекущиеДанные.Имя,
														Истина);
		ИначеЕсли ТекущиеДанные.Тип = Типы.ПолеФормы Тогда
			МенеджерПрототипов.УдалитьЭлементУправления(СтрокаПрототипа.Идентификатор,
														ТекущиеДанные.Имя,
														ТекущиеДанные.Имя,
														Истина,
														ТекущиеДанные.ЭтоКолонка,
														ТекущиеДанные.ИмяТаблицы);
		ИначеЕсли ТекущиеДанные.Тип = Типы.ГруппаФормы Или ТекущиеДанные.Тип = Типы.ДекорацияФормы Тогда

			МенеджерПрототипов.УдалитьЭлементУправления(СтрокаПрототипа.Идентификатор, ТекущиеДанные.Имя, "", Ложь);
		Иначе
			МенеджерПрототипов.УдалитьЭлементУправления(СтрокаПрототипа.Идентификатор,
														ТекущиеДанные.Имя,
														ТекущиеДанные.Имя,
														Ложь);
		КонецЕсли;

		Родитель = ТекущиеДанные.ПолучитьРодителя();
		Родитель.ПолучитьЭлементы().Удалить(ТекущиеДанные);

		СтрокаПрототипа.Модифицированность = Истина;
		СтрокаПрототипа.ИндексКартинки = ИндексКартинкиФормы(Истина);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьСвойстваПервымЗначениемДанныхВыбора(НоваяСтрока)
	ПараметрыОтбора = ПолучитьПараметрыОтбораСвойств(НоваяСтрока);
	ПараметрыОтбора.Вставить("ВариантЗаполнения", ВариантыЗаполнения.ВыборИзВыпадающегоСписка);

	ИскомыеСтроки = СвойстваФормИЭлементовУправления.НайтиСтроки(ПараметрыОтбора);
	Для Каждого Строка Из ИскомыеСтроки Цикл
		ИмяДанныхВыбора = ПолучитьИмяДанныхВыбора(Строка.Свойство, НоваяСтрока.Тип, НоваяСтрока.Вид);
		НоваяСтрока[Строка.Свойство] = Строка[ИмяДанныхВыбора][0].Значение;

	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьСвойствоПервымЗначениемДанныхВыбора(НоваяСтрока, Свойство)
	ИмяДанныхВыбора = ПолучитьИмяДанныхВыбора(Свойство, НоваяСтрока.Тип, НоваяСтрока.Вид);

	ПараметрыОтбора = Новый Структура("Свойство", Свойство);
	ИскомыеСтроки = СвойстваФормИЭлементовУправления.НайтиСтроки(ПараметрыОтбора);

	НоваяСтрока[Свойство] = ИскомыеСтроки[0][ИмяДанныхВыбора][0].Значение;

КонецПроцедуры

&НаКлиенте
Функция ПолучитьКлючиСпециальныеСвойства()

	Результат = "Идентификатор,Имя,Тип,Вид,ИмяРодителя,Прототип,Путь,ПутьКДанным,ТипЗначения,Длина,Точность,СоставДаты";
	Возврат Результат;

КонецФункции

&НаКлиенте
Функция ПолучитьКлючиТиповыхСвойств(НоваяСтрока, КлючиСпециальныеСвойства)
	Результат = "";

	ПараметрыОтбора = ПолучитьПараметрыОтбораСвойств(НоваяСтрока);

	ИскомыеСтроки = СвойстваФормИЭлементовУправления.НайтиСтроки(ПараметрыОтбора);
	Для Каждого Строка Из ИскомыеСтроки Цикл
		Если Найти(КлючиСпециальныеСвойства, Строка.Свойство) > 0 Тогда
			Продолжить;
		КонецЕсли;

		Результат = Результат + "," + Строка.Свойство;

	КонецЦикла;

	Возврат Сред(Результат, 2);
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ПолучитьИменаДанныхВыбора()
	ИменаДанныхВыбора = Новый Массив;
	ИменаДанныхВыбора.Добавить("ДанныеВыбора");
	ИменаДанныхВыбора.Добавить("ДанныеВыбора_ГруппаКолонок");
	ИменаДанныхВыбора.Добавить("ДанныеВыбора_Кнопка");

	Возврат ИменаДанныхВыбора;
КонецФункции

&НаКлиенте
Процедура ЗначениеНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;

	Если РежимРедактированияСвойств Тогда
		Возврат;
	КонецЕсли;

	ТекущиеДанныеПрототип = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	ТекущиеДанныеСвойства = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;

	Если ТекущиеДанныеСвойства.ВариантЗаполнения = ВариантыЗаполнения.ВводМножестваЗначений Тогда
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("Заголовок", ТекущиеДанныеСвойства.СвойствоПредставление);
		ПараметрыФормы.Вставить("Значение", ТекущиеДанныеСвойства.Значение);
		ПараметрыФормы.Вставить("ТипЗначенияСписка", ТекущиеДанныеПрототип.ТипЗначения);

		ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("МножественныйВводЗавершение", ЭтотОбъект);
		ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.ВводСпискаЗначений",
					 ПараметрыФормы,
					 ЭтотОбъект,
					 ,
					 ,
					 ,
					 ОписаниеОповещенияОЗакрытии,
					 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

	ИначеЕсли ТекущиеДанныеСвойства.ВариантЗаполнения = ВариантыЗаполнения.ВыборИзВыпадающегоСписка Тогда
		ОписаниеОповещения = Новый ОписаниеОповещения("ВыборИзВыпадающегоСпискаЗавершение", ЭтотОбъект);

		ИмяДанныхВыбора = ПолучитьИмяДанныхВыбора(ТекущиеДанныеСвойства.Свойство,
												  ТекущиеДанныеПрототип.Тип,
												  ТекущиеДанныеПрототип.Вид);
		ПоказатьВыборИзМеню(ОписаниеОповещения,
							ТекущиеДанныеСвойства[ИмяДанныхВыбора],
							Элементы.СвойстваФормИЭлементовУправления.ТекущийЭлемент);

	ИначеЕсли ТекущиеДанныеСвойства.ВариантЗаполнения = ВариантыЗаполнения.ВыборКартинки Тогда

		ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("ВыборКартинкиЗавершение", ЭтотОбъект);
		ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.ВыборКартинки",
					 ПараметрыФормы,
					 ЭтаФорма,
					 ,
					 ,
					 ,
					 ОписаниеОповещенияОЗакрытии,
					 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

	ИначеЕсли ТекущиеДанныеСвойства.ВариантЗаполнения = ВариантыЗаполнения.ВводЗначения Тогда
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("Заголовок", ТекущиеДанныеСвойства.СвойствоПредставление);
		ПараметрыФормы.Вставить("Значение", ТекущиеДанныеСвойства.Значение);

		ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("ВводЗавершение", ЭтотОбъект);

		Если ТипЗнч(ТекущиеДанныеСвойства.Значение) = Тип("Строка") Тогда
			ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.ВводСтроки",
						 ПараметрыФормы,
						 ЭтотОбъект,
						 ,
						 ,
						 ,
						 ОписаниеОповещенияОЗакрытии,
						 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

		ИначеЕсли ТипЗнч(ТекущиеДанныеСвойства.Значение) = Тип("Число") Тогда
			ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.ВводЧисла",
						 ПараметрыФормы,
						 ЭтотОбъект,
						 ,
						 ,
						 ,
						 ОписаниеОповещенияОЗакрытии,
						 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

		КонецЕсли;
	ИначеЕсли ТекущиеДанныеСвойства.ВариантЗаполнения = ВариантыЗаполнения.ВыборЦвета Тогда
		ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("ВыборЦветаЗавершение", ЭтотОбъект);
		ДиалогВыбораЦвета = Новый ДиалогВыбораЦвета;
		ДиалогВыбораЦвета.Показать(ОписаниеОповещенияОЗакрытии);

	ИначеЕсли ТекущиеДанныеСвойства.ВариантЗаполнения = ВариантыЗаполнения.ВыборШрифта Тогда
		ОписаниеОповещенияОЗакрытии = Новый ОписаниеОповещения("ВыборШрифтаЗавершение", ЭтотОбъект);
		ДиалогВыбораЦвета = Новый ДиалогВыбораШрифта;
		ДиалогВыбораЦвета.Показать(ОписаниеОповещенияОЗакрытии);

	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция ПолучитьИмяДанныхВыбора(Свойство, Тип, Вид)
	Результат = "";
	
	// Отдельно обрабатывать только свойства с несколькими данными выбора
	Если Свойство = "Группировка" Тогда
		Если Вид = Виды.ГруппаКолонок Тогда
			Результат = "ДанныеВыбора_ГруппаКолонок";

		Иначе
			Результат = "ДанныеВыбора";

		КонецЕсли;
	ИначеЕсли Свойство = "Отображение" Тогда
		Если Ложь Или Тип = Типы.КнопкаФормы Или Вид = Виды.Подменю Тогда

			Результат = "ДанныеВыбора_Кнопка";

		Иначе
			Результат = "ДанныеВыбора";

		КонецЕсли;
	Иначе
		Результат = "ДанныеВыбора";

	КонецЕсли;

	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура ВводЗавершение(Результат, ДополнительныеПараметры) Экспорт

	Если Результат = Неопределено Тогда
		Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

		Возврат;
	КонецЕсли;

	ТекущиеДанныеСвойства = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;
	ТекущиеДанныеСвойства.Значение = Результат;
	ОбновитьПредставлениеЗначенияСвойства(ТекущиеДанныеСвойства);

	Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

	ОбработатьИзменениеСвойства();

КонецПроцедуры

&НаКлиенте
Процедура ВыборИзВыпадающегоСпискаЗавершение(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт

	ТекущиеДанныеСвойства = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;
	Если Не ВыбранныйЭлемент = Неопределено Тогда
		ТекущиеДанныеСвойства.Значение = ВыбранныйЭлемент.Значение;
		ТекущиеДанныеСвойства.ЗначениеПредставление = ВыбранныйЭлемент.Представление;

		ОбработатьИзменениеСвойства();
		ОпределитьСвойства();
	КонецЕсли;

	Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

КонецПроцедуры

&НаКлиенте
Процедура ВыборКартинкиЗавершение(РезультатЗакрытия, ДополнительныеПараметры) Экспорт

	Если РезультатЗакрытия = Неопределено Тогда
		Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

		Возврат;
	КонецЕсли;

	ТекущиеДанныеСвойства = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;
	ТекущиеДанныеСвойства.Значение = РезультатЗакрытия.Значение;
	ТекущиеДанныеСвойства.ЗначениеПредставление = РезультатЗакрытия.Представление;

	ОбработатьИзменениеСвойства();

	ОпределитьСвойства();

	Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

КонецПроцедуры

&НаКлиенте
Процедура ВыборЦветаЗавершение(Цвет, ДополнительныеПараметры) Экспорт

	Если Цвет = Неопределено Тогда
		Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

		Возврат;
	КонецЕсли;

	ТекущиеДанныеСвойства = Элементы.СвойстваФормИЭлементовУправления.ТекущиеДанные;
	Если Цвет.Вид = ВидЦвета.Абсолютный Тогда
		ТекущиеДанныеСвойства.Значение = "Новый Цвет(" + Цвет.Зеленый + "," + Цвет.Красный + "," + Цвет.Синий + ")";
		ТекущиеДанныеСвойства.ЗначениеПредставление = "Абсолютный: " + Строка(Цвет);
	ИначеЕсли Цвет.Вид = ВидЦвета.WebЦвет Тогда
		ДанныеВебЦвета = МенеджерНаборовЗначений.ДанныеВебЦвета(Цвет);
		ТекущиеДанныеСвойства.Значение = ДанныеВебЦвета.Значение;
		ТекущиеДанныеСвойства.ЗначениеПредставление = ДанныеВебЦвета.Представление;
	ИначеЕсли Цвет.Вид = ВидЦвета.ЭлементСтиля Тогда
		ДанныеЦветаСтиля = МенеджерНаборовЗначений.ДанныеЦветаСтиля(Цвет);
		ТекущиеДанныеСвойства.Значение = ДанныеЦветаСтиля.Значение;
		ТекущиеДанныеСвойства.ЗначениеПредставление = ДанныеЦветаСтиля.Представление;
	КонецЕсли;

	Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

	ОбработатьИзменениеСвойства();

КонецПроцедуры

&НаКлиенте
Процедура ВыборШрифтаЗавершение(Шрифт, ДополнительныеПараметры) Экспорт

	Если Шрифт = Неопределено Тогда
		Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

		Возврат;
	КонецЕсли;

	Элементы.СвойстваФормИЭлементовУправления.ЗакончитьРедактированиеСтроки(Ложь);

	ОбработатьИзменениеСвойства();

КонецПроцедуры

&НаКлиенте
Функция ИндексКартинкиФормы(ЕстьИзменения)

	Результат = ?(ЕстьИзменения, 28, 0);
	Возврат Результат;

КонецФункции

&НаКлиенте
Процедура ПодготовитьСчетчики(ИдентификаторПрототипа)

	Если Счетчики = Неопределено Тогда
		Счетчики = Новый Соответствие;
	КонецЕсли;

	СчетчикиЭлементовУправления = Новый Структура;
	Для Каждого Вид Из Виды Цикл
		СчетчикиЭлементовУправления.Вставить(Вид.Ключ, 0);
	КонецЦикла;
	Для Каждого Тип Из Типы Цикл
		СчетчикиЭлементовУправления.Вставить(Тип.Ключ, 0);
	КонецЦикла;

	Счетчики.Вставить(ИдентификаторПрототипа, СчетчикиЭлементовУправления);

КонецПроцедуры

&НаКлиенте
Функция НовоеИмяЭлементаУправления(ИдентификаторПрототипа, Вид, Тип)

	Если ЗначениеЗаполнено(Вид) Тогда
		ИмяСчетчика = Вид;
	Иначе
		ИмяСчетчика = Тип;
	КонецЕсли;

	Счетчики[ИдентификаторПрототипа][ИмяСчетчика] = Счетчики[ИдентификаторПрототипа][ИмяСчетчика] + 1;
	Возврат СтрШаблон("%1%2", ИмяСчетчика, Счетчики[ИдентификаторПрототипа][ИмяСчетчика]);

КонецФункции

&НаКлиенте
Процедура УдалитьИзСчетчиков(ИдентификаторПрототипа)

	Счетчики.Удалить(ИдентификаторПрототипа);

КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьПрототипИзОткрытойФормы(Команда)

	//TODO:
//	1) добавить в макет ФормыИЭлементыУправление все колонки дерева
//	1.1) доработать алгоритм заполнения дерева, чтобы не было ошибки
//	2) Реализовать расширение с методом в общем модуле, который на сервере будет 
//	
	ПараметрыВыбораФормы = Новый Структура;
	ПараметрыВыбораФормы.Вставить("ИсточникФорм", "ИзПредприятия");

	ОповещенияОЗакрытии = Новый ОписаниеОповещения("ПослеВыбораФормыДляСканирования", ЭтотОбъект);

	ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.ВыборФормы",
				 ПараметрыВыбораФормы,
				 ,
				 ,
				 ,
				 ,
				 ОповещенияОЗакрытии);

КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораФормыДляСканирования(ФормаДляСканирования, ДополнительныеПараметры) Экспорт

	Если ФормаДляСканирования = Неопределено Тогда
		//TODO: нужно проинформировать пользователя почему...
		Возврат;
	КонецЕсли;
	ДанныеСтроки = Элементы.ФормыИЭлементыУправления.ТекущиеДанные;
	СтрокаПрототип = ПолучитьСтрокуПрототипаРекурсивно(ДанныеСтроки);
	ЗагрузитьОткрытуюФормуВПрототипРекурсивно(СтрокаПрототип, ФормаДляСканирования.ПодчиненныеЭлементы);

КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьОткрытуюФормуВПрототипРекурсивно(ТекущаяСтрока, КоллекцияЭлементов)

	Для Каждого Элемент Из КоллекцияЭлементов Цикл
		// TODO: кажется контекстое меню элементов создается автоматически, т.е. не нужно или невозможго его добавить.
		//Если Элемент.Вид = ВидГруппыФормы.КонтекстноеМеню Тогда
		//	Продолжить;
		//КонецЕсли;

		ЕстьПодчиненныеЭлементы = Ложь;

		ТипЗначенияТекущегоЭлемента = ТипЗнч(Элемент);
		Если ТипЗначенияТекущегоЭлемента = Тип("ПолеФормы") Тогда
			Если Элемент.Вид = ВидПоляФормы.ПолеВвода Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеВвода, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеФлажка Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеФлажка, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеПереключателя Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеПереключателя, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеКартинки Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеКартинки, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеИндикатора Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеИндикатора, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеПолосыРегулирования Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы,
													  Виды.ПолеПолосыРегулирования,
													  ,
													  Элемент,
													  ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеКалендаря Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеКалендаря, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеФорматированногоДокумента Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы,
													  Виды.ПолеФорматированногоДокумента,
													  ,
													  Элемент,
													  ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеНадписи Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы, Виды.ПолеНадписи, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеТекстовогоДокумента Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы,
													  Виды.ПолеТекстовогоДокумента,
													  ,
													  Элемент,
													  ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ПолеФормы,
													  Виды.ПолеТабличногоДокумента,
													  ,
													  Элемент,
													  ТекущаяСтрока);
			КонецЕсли;
		ИначеЕсли ТипЗначенияТекущегоЭлемента = Тип("ГруппаФормы") Тогда
			ЕстьПодчиненныеЭлементы = Истина;

			Если Элемент.Вид = ВидГруппыФормы.ОбычнаяГруппа Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ГруппаФормы, Виды.ОбычнаяГруппа, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидГруппыФормы.КоманднаяПанель Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ГруппаФормы, Виды.КоманднаяПанель, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидГруппыФормы.Подменю Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ГруппаФормы, Виды.Подменю, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидГруппыФормы.Страницы Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ГруппаФормы, Виды.Страницы, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидГруппыФормы.Страница Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ГруппаФормы, Виды.Страница, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидГруппыФормы.ГруппаКолонок Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ГруппаФормы, Виды.ГруппаКолонок, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидГруппыФормы.КонтекстноеМеню Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ГруппаФормы, Виды.КонтекстноеМеню, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидГруппыФормы.ГруппаКнопок Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.ГруппаФормы, Виды.ГруппаКнопок, , Элемент, ТекущаяСтрока);
			КонецЕсли;
		ИначеЕсли ТипЗначенияТекущегоЭлемента = Тип("КнопкаФормы") Тогда
			Если Элемент.Вид = ВидКнопкиФормы.ОбычнаяКнопка Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.КнопкаФормы, Виды.ОбычнаяКнопка, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.КнопкаФормы,
													  Виды.КнопкаКоманднойПанели,
													  ,
													  Элемент,
													  ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидКнопкиФормы.Гиперссылка Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.КнопкаФормы, Виды.Гиперссылка, , Элемент, ТекущаяСтрока);
			ИначеЕсли Элемент.Вид = ВидКнопкиФормы.ГиперссылкаКоманднойПанели Тогда
				НовыйЭлемент = НовыйЭлементУправления(Типы.КнопкаФормы,
													  Виды.ГиперссылкаКоманднойПанели,
													  ,
													  Элемент,
													  ТекущаяСтрока);
			КонецЕсли;
		ИначеЕсли ТипЗначенияТекущегоЭлемента = Тип("ТаблицаФормы") Тогда
			ЕстьПодчиненныеЭлементы = Истина;

			НовыйЭлемент = НовыйЭлементУправления(Типы.ТаблицаФормы,
												  ,
												  ТипыЗначения.ТаблицаЗначений,
												  Элемент,
												  ТекущаяСтрока);
		ИначеЕсли ТипЗначенияТекущегоЭлемента = Тип("ДекорацияФормы") Тогда
			НовыйЭлемент = НовыйЭлементУправления(Типы.ДекорацияФормы, Виды.Надпись, , Элемент, ТекущаяСтрока);
		КонецЕсли;

		Если ЕстьПодчиненныеЭлементы Тогда
			ЗагрузитьОткрытуюФормуВПрототипРекурсивно(НовыйЭлемент, Элемент.ПодчиненныеЭлементы);
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьСвойстваИзИсточника(НоваяСтрока, Источник)

	ПараметрыОтбора = ПолучитьПараметрыОтбораСвойств(НоваяСтрока);

	ИсключаемыеСвойства = Новый Массив;
	ИсключаемыеСвойства.Добавить("Заголовок");
	ИсключаемыеСвойства.Добавить("ТипЗначения");
	ИсключаемыеСвойства.Добавить("Длина");
	ИсключаемыеСвойства.Добавить("Точность");
	ИсключаемыеСвойства.Добавить("НомерСтроки");
	//TODO: Данное свойство недоступно для декорации, используемой как расширенная подсказка
	ИсключаемыеСвойства.Добавить("Подсказка");
	ИсключаемыеСвойства.Добавить("ОтображениеПодсказки");

	ИскомыеСвойства = СвойстваФормИЭлементовУправления.НайтиСтроки(ПараметрыОтбора);
	Для Каждого ДанныеСвойства Из ИскомыеСвойства Цикл
		ТекущееСвойство = ДанныеСвойства.Свойство;
		Если ИсключаемыеСвойства.Найти(ТекущееСвойство) = Неопределено Тогда
			ЗначениеСвойства = Вычислить("Источник." + ТекущееСвойство + "");
			Если ТекущееСвойство = "Группировка" Тогда
				Если ЗначениеСвойства = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная Тогда
					ЗначениеСвойства = "Вертикальная";
				ИначеЕсли ЗначениеСвойства = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда Тогда
					ЗначениеСвойства = "ГоризонтальнаяВсегда";
				ИначеЕсли ЗначениеСвойства = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяЕслиВозможно Тогда
					ЗначениеСвойства = "ГоризонтальнаяЕслиВозможно";
				КонецЕсли;
			КонецЕсли;
			НоваяСтрока[ТекущееСвойство] = ЗначениеСвойства;
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьПрототипИзФормыКонфигурации(Команда)

	ПараметрыВыбораФормы = Новый Структура;
	ПараметрыВыбораФормы.Вставить("ИсточникФорм", "ИзКонфигуратора");

	ОповещенияОЗакрытии = Новый ОписаниеОповещения("ПослеВыбораФормыДляСканирования", ЭтотОбъект);

	ОткрытьФорму("Обработка.УИ_РедакторПрототиповФорм.Форма.ВыборФормы",
				 ПараметрыВыбораФормы,
				 ,
				 ,
				 ,
				 ,
				 ОповещенияОЗакрытии);

КонецПроцедуры

&НаСервере
Функция НовыйФайлПрототипа()

	Результат = Новый Структура;
	Результат.Вставить("Версия");
	Результат.Вставить("Элементы");

	Возврат Результат;

КонецФункции

&НаКлиенте
Процедура ОбновитьПредставлениеЗначенияСвойства(СтрокаСвойства)

	ПредставлениеПустогоЗначения = "...";
	СтрокаСвойства.ЗначениеПредставление = ?(ЗначениеЗаполнено(СтрокаСвойства.Значение),
											 СтрокаСвойства.Значение,
											 ПредставлениеПустогоЗначения);

КонецПроцедуры


&НаСервере
Функция ОписаниеПрототипаДляСохраненияВФайлНаСервере(СтрокаПрототипа)

	Результат = Ложь;

	ФормыИЭлементыУправленияНаСервере = РеквизитФормыВЗначение("ФормыИЭлементыУправления");
	ИскомаяСтрока = ФормыИЭлементыУправленияНаСервере.Строки.Найти(СтрокаПрототипа.Идентификатор, "Идентификатор");

	КолонкиИсключения = Новый Массив;
	КолонкиИсключения.Добавить("Модифицированность");
	КолонкиИсключения.Добавить("РасположениеФайла");
	КолонкиИсключения.Добавить("Родитель");

	Ключи = "Элементы";
	Для Каждого Колонка Из ФормыИЭлементыУправленияНаСервере.Колонки Цикл
		Если Не КолонкиИсключения.Найти(Колонка.Имя) = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		Ключи = Ключи + "," + Колонка.Имя;
	КонецЦикла;

	ВременныйМассив = Новый Массив;
	ВременныйМассив.Добавить(ИскомаяСтрока);

	ОписаниеПрототипа = ФормыИЭлементыУправленияВМассивРекурсивно(ВременныйМассив, Ключи, "ИндексКартинки");
	Возврат ОписаниеПрототипа;

КонецФункции

&НаКлиенте
Процедура ПрочитатьФайлПрототиповНаКлиенте(АдресФайлаВоВременномХранилище)
	ПрочитатьФайлПрототиповНаСервере(АдресФайлаВоВременномХранилище);
	
	МенеджерПрототипов.ЗакрытьВсеФормы();
	МенеджерПрототипов.Инициализировать();
	
	ЗагрузитьПрототипРекурсивно(ФормыИЭлементыУправления.ПолучитьЭлементы());
КонецПроцедуры

&НаСервере
Процедура ПрочитатьФайлПрототиповНаСервере(АдресФайлаВоВременномХранилище)
	ДанныеФайла=ПолучитьИзВременногоХранилища(АдресФайлаВоВременномХранилище);//ДвоичныеДанные
	
	СтруктураФайла = ДесериализоватьИзJSON(ДанныеФайла.ОткрытьПотокДляЧтения());

	ВерсияФормата = 1;
	Если СтруктураФайла.Свойство("ВерсияФормата") Тогда
		ВерсияФормата = СтруктураФайла.ВерсияФормата;
	КонецЕсли;

	ФормыИЭлементыУправленияНаСервере = РеквизитФормыВЗначение("ФормыИЭлементыУправления");
	ФормыИЭлементыУправленияНаСервере.Строки.Очистить();
	
	
	Замена = Ложь;
//	Для Каждого ТекПрототип ИЗ СтруктураФайла.Прототипы Цикл

		ФормыИЭлементыУправленияИзМассиваРекурсивно(СтруктураФайла.Прототипы ,
													ФормыИЭлементыУправленияНаСервере.Строки,
													Истина,
													Замена,
													"");

		
//	КонецЦикла;
	ЗначениеВРеквизитФормы(ФормыИЭлементыУправленияНаСервере, "ФормыИЭлементыУправления");
//	
//	Алгоритмы.ПолучитьЭлементы().Очистить();
//	
//	Если ВерсияФормата = 1 Тогда
//		ЗаполнитьФормуПоФорматуВерсии_1(СтруктураФайла);
//	Иначе
//		ЗаполнитьАлгоритмыПоФорматуВерсии_2(СтруктураФайла);
//	КонецЕсли;

КонецПроцедуры

#Область СтандартныеПроцедурыИнструментов

&НаКлиенте
Функция СтруктураОписанияСохраняемогоФайла()
	Структура=УИ_ОбщегоНазначенияКлиент.ПустаяСтруктураОписанияВыбираемогоФайла();
	Структура.ИмяФайла=ИмяФайлаДанныхИнструмента;
	
	УИ_ОбщегоНазначенияКлиент.ДобавитьФорматВОписаниеФайлаСохранения(Структура,
																	 "Файл прототипов форм(*.xuiproto)",
																	 "xuiproto");
	Возврат Структура;
КонецФункции

&НаКлиенте
Процедура ОткрытьФайлЗавершение(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Модифицированность=Ложь;
	ИмяФайлаДанныхИнструмента = Результат.ИмяФайла;
	
	ПрочитатьФайлПрототиповНаКлиенте(Результат.Адрес);
	
	УстановитьЗаголовок();

КонецПроцедуры

&НаКлиенте
Процедура СохранитьФайлНаДиск(СохранитьКак = Ложь)
	ДопПараметрыОповещения = Неопределено;
	
	УИ_ОбщегоНазначенияКлиент.СохранитьДанныеКонсолиВФайл("КонсольКода", СохранитьКак,
		СтруктураОписанияСохраняемогоФайла(), СтрокаСохраненияВФайл(),
		Новый ОписаниеОповещения("СохранитьФайлЗавершение", ЭтотОбъект, ДопПараметрыОповещения));
КонецПроцедуры

&НаКлиенте
Процедура СохранитьФайлЗавершение(ИмяФайлаСохранения, ДополнительныеПараметры) Экспорт
	Если ИмяФайлаСохранения = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если Не ЗначениеЗаполнено(ИмяФайлаСохранения) Тогда
		Возврат;
	КонецЕсли;

	Модифицированность=Ложь;
	ИмяФайлаДанныхИнструмента=ИмяФайлаСохранения;
	УстановитьЗаголовок();
	
	Для Каждого Стр ИЗ ФормыИЭлементыУправления.ПолучитьЭлементы() Цикл
		Стр.Модифицированность = Ложь;
		Стр.ИндексКартинки = ИндексКартинкиФормы(Стр.Модифицированность);

	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура УстановитьЗаголовок()
	Заголовок = ИмяФайлаДанныхИнструмента;
КонецПроцедуры 

&НаСервере
Функция ОписаниеПрототиповДляСохраненияВФайл()
	ФормыИЭлементыУправленияНаСервере = РеквизитФормыВЗначение("ФормыИЭлементыУправления");

	КолонкиИсключения = Новый Массив;
	КолонкиИсключения.Добавить("Модифицированность");
	КолонкиИсключения.Добавить("РасположениеФайла");
	КолонкиИсключения.Добавить("Родитель");

	Ключи = "Элементы";
	Для Каждого Колонка Из ФормыИЭлементыУправленияНаСервере.Колонки Цикл
		Если Не КолонкиИсключения.Найти(Колонка.Имя) = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		Ключи = Ключи + "," + Колонка.Имя;
	КонецЦикла;

	ВременныйМассив = Новый Массив;
	Для Каждого СтрИз  Из ФормыИЭлементыУправленияНаСервере.Строки Цикл
		ВременныйМассив.Добавить(СтрИз);
	КонецЦикла;	

	ОписаниеПрототипа = ФормыИЭлементыУправленияВМассивРекурсивно(ВременныйМассив, Ключи, "ИндексКартинки");
	Возврат ОписаниеПрототипа;	
	
КонецФункции	

&НаСервере
Функция СтрокаСохраненияВФайл()
	СохраняемыеДанные = Новый Структура;
	СохраняемыеДанные.Вставить("ВерсияФормата", 1);
	СохраняемыеДанные.Вставить("Прототипы", ОписаниеПрототиповДляСохраненияВФайл());
	
	Возврат СериализоватьВJSON(СохраняемыеДанные);
	
КонецФункции



#КонецОбласти

#КонецОбласти